默认
发表评论 5
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
Soul 千万级 IM搭建分享-网络层搭建
阅读(34648) | 评论(5 收藏 淘帖
[h1Head]接下来讲解一下socket编程的大体流程[/h1Head]

1.创建一个socket套接字,指定协议 tpc udp和ipv4/ipv6


int socketFD = socket(AF_INET, SOCK_STREAM, 0);

2.根据ip和端口解析地址清单。gettaddrinfo函数能够处理名字到地址的转换,返回的是一个sockaddr结构的链表而不是一个地址清单,这些sockaddr结构随后可由套接口函数直接使用。


         struct addrinfo hints, *res, *res0;
      memset(&hints, 0, sizeof(hints));
      hints.ai_family   = PF_UNSPEC;
      hints.ai_socktype = SOCK_STREAM;
      hints.ai_protocol = IPPROTO_TCP;
      const char *serverPort = [port UTF8String];
      const char *serverHost = [host UTF8String];
      int gai_error = getaddrinfo(serverHost, serverPort, &hints, &res0); //获取网络地址

3.建立三路握手,获取一个稳定的tcp连接,其中connect函数会与远端服务器建立连接,服务端会调accept调用接收连接请求。


NSData *addInfo = [NSData dataWithBytes:resultInfo->ai_addr length:resultInfo->ai_addrlen];
int connected = connect(self->_socketFD, (const struct sockaddr *)[data bytes], (socklen_t)[data length]);

4.基于这个连接,实现收发流接口,socketFD类似于一个连接或者文件的句柄

int cnt = (int)write(socketFD, data, size); //写缓冲区
int cnt = (int)read(socketFD, buffer ,size); //从缓冲区读数据


因为客户端只需实现建立连接,也就是一个通道套接字,就是socketId,无需像服务端一样做accept做多路连接处理,所以实现较为简单。
在连接简历后,会调用read函数从缓冲区读取数据,但这里要注意一下,由于此时socket是阻塞式的,在缓冲区没有数据到达时,线程会阻塞在read函数中,所以这里建议用while(1)循环处理。
之所以不建议改成非阻塞方式,之所以没有用非阻塞read:1、实现简单,2、非阻塞方式有多种实现方式,如设置超时时间循环读,设置定时器定时读取等,实现复杂,实时性略差,好处是不用阻塞线程。
read之前要事先初始化一份内存,用于存放读取的数据,这里默认8K的buffer。
设置两个指针,一个指向buffer的头部topPtr,一个指向内存的增长末端nextPt,指定读取100个字节时:


              int size = 100;
       while(1) {
                 int cnt = (int)read(socketFD, nextptr, size); //阻塞式读
        if(cnt >0) {
       if (cnt< 100) { //有可能一次读取无法完全读完指定的大小字节数
           size-=cnt;
            nextPt+= cnt;
         }
        } else if (cnt ==0) { //对端关闭socket
         close(socketFD);
         return;
     } else {
      if((cnt<0) &&(errno == EAGAIN||errno == EWOULDBLOCK||errno == EINTR)) {
          continue;
       }
       return;
      }
}

至于为何cnt可能无法一次读取100个字节,请查看下面的链接:Soul自研IM之网络层异常状况处理

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

上一篇:IM开发干货分享:有赞移动端IM的组件化SDK架构设计实践下一篇:Soul自研IM之搭建自己的网络层
推荐方案
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部