[IOS&SOCKET]SOCKET切换网络,SOCKET链路不通

在IM项目中,socket建立成功且进行发送socket成功后,切换网络后会导致发送消息失败!

经过多次测试得出规律:

1: 移动网络环境建立的socket连接,那么切换到wifi后,发送消息失败;

2: wifi网络环境建立的socket连接,那么切换到4g后,发送消息失败;


那么,难道socket在某一网络环境下建立的socket链路,那么切换网络后,还是使用原来的SOCKET链路吗?

测试结果是符合这样的,但是为什么其他IM 产品却没有表现出类似的情况呢?


经过N多搜查资料,还是没有看到APPLE对IOS SOCKET 建立与网络的说明。但是在stackoverflow上找到一个类似的问题情况,

最终决定,在切换网络的时候,关闭链路,重新建立连接解决!


        /*
         *   ==============================================================================
         *   1: 网络环境若从wifi切换到2g/3g/4g,那么需要关闭AsynShutdown,然后重建立连接AsynConnect
         *   2: 网络环境若从2g/3g/4g切换到wifi,那么需要关闭AsynShutdown,然后重建立连接AsynConnect.
         *   ==============================================================================
         */


PS:切换网络(4g to wifi )后,需要重建立链接是正常的,因为链路路由都不一样了!


参考:

http://stackoverflow.com/questions/30480599/sometimes-socket-dies-when-switching-wifi-to-3g-ios-posix-sockets

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iOS 中使用 BSD Socket 进行网络编程时,可以使用 select 函数来实现多路复用。 select 函数可以监视多个文件描述符的状态,当其中有文件描述符发生变化时,select 函数就会返回,并且可以通过返回的结果来判断是哪些文件描述符发生了变化。 具体使用步骤如下: 1. 创建 socket。 2. 绑定 socket。 3. 监听 socket。 4. 创建 fd_set 集合,将需要监视的文件描述符加入集合中。 5. 调用 select 函数,等待文件描述符状态变化。 6. 根据 select 函数的返回结果,判断是哪些文件描述符发生了变化。 7. 处理变化的文件描述符。 下面是一个简单的示例代码: ``` #include <sys/select.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int main() { int listenSocket = socket(AF_INET, SOCK_STREAM, 0); if (listenSocket < 0) { perror("socket"); return 1; } struct sockaddr_in serverAddr; memset(&serverAddr, 0, sizeof(serverAddr)); serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(12345); serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(listenSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) != 0) { perror("bind"); close(listenSocket); return 1; } if (listen(listenSocket, 5) != 0) { perror("listen"); close(listenSocket); return 1; } fd_set readFds; FD_ZERO(&readFds); FD_SET(listenSocket, &readFds); while (true) { fd_set tmpFds = readFds; int maxFd = listenSocket; if (select(maxFd + 1, &tmpFds, NULL, NULL, NULL) < 0) { perror("select"); close(listenSocket); return 1; } for (int i = 0; i <= maxFd; ++i) { if (FD_ISSET(i, &tmpFds)) { if (i == listenSocket) { // 有新的连接请求 struct sockaddr_in clientAddr; socklen_t addrLen = sizeof(clientAddr); int clientSocket = accept(listenSocket, (struct sockaddr *)&clientAddr, &addrLen); if (clientSocket < 0) { perror("accept"); close(listenSocket); return 1; } printf("New connection from %s:%d\n", inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port)); FD_SET(clientSocket, &readFds); if (clientSocket > maxFd) { maxFd = clientSocket; } } else { // 有数据可读 char buf[1024]; int len = recv(i, buf, sizeof(buf), 0); if (len < 0) { perror("recv"); close(listenSocket); return 1; } else if (len == 0) { printf("Connection closed\n"); close(i); FD_CLR(i, &readFds); } else { buf[len] = '\0'; printf("Received: %s\n", buf); } } } } } return 0; } ``` 这个示例代码实现了一个简单的 TCP 服务器,可以接受客户端的连接,并且当有数据可读时,会打印出来。在主循环中,我们使用 select 函数等待文件描述符状态变化,当有新的连接请求或者有数据可读时,就会通过 if 语句来判断是哪些文件描述符发生了变化,并且进行相应的处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值