问题描述
- 关于socket通信,多线程发送消息
-
最近在多线程中使用socket通信遇到的问题,场景是有多个线程需要用到同一个socket连接进行消息的发送,因为没有订具体的协议,所以对于发送(文本)消息,每次发送端发送1K字节,接收端每次接收1K字节,无效数据用0填充,正常情况下来说都没什么问题,但当接收方接收不过来时,由于发送方设置了发送超时(30ms),send会发出EWOULDBLOCK,这下问题来了,推消息设计时设置超时就是希望对方不收就扔掉,
那么如果收到EWOULDBLOCK 就返回,那么这次1K数据发送不全,接收方收的1k数据实际不是想要的数据,但如果收到EWOULDBLOCK 不停重新发送,那么这个线程都会阻塞住,违背设计原则,就算将tcp设置为非阻塞,也会在send缓冲满时出同样问题,现在我能想到的一个解决思路是将发消息单独放到另外一个线程,将所有消息先放到一个队列,发消息的线程再从队列中取消息,不过这样做涉及到队列的加解锁,效率好像很低,有没有更好的思路解决这样的问题,谢谢
解决方案
Socket 多线程通信
多线程socket通信client
自己实现的socket多线程通信
解决方案二:
你的想法是对的,就应该放到一个队列中去,不用加锁的,你可以在对方收到消息后返回一个信息,你接收到这个信息后在发送下一个
解决方案三:
还有几个问题不知道有没有哪位兄弟帮解释下
1 windows socket 如何判断一个SOCKET是否是有效的,比如linux可以
getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len);
if(info.tcpi_state== 1) {
printf("socket connected
");
return 1;
} else {
printf("socket disconnected
");
return 0;
、 }
windows 不是太熟试了几个都不行,也没有结构体比如这个试了没用
bool ret = false;
HANDLE closeEvent = WSACreateEvent();
WSAEventSelect(clientSocket, closeEvent, FD_CLOSE);
DWORD dwRet = WaitForSingleObject(closeEvent, 0);
if(dwRet == WSA_WAIT_EVENT_0)
ret = true;
else if(dwRet == WSA_WAIT_TIMEOUT)
ret = false;
WSACloseEvent(closeEvent);
return ret;
2,windows上对于socket错误除了有没有具体信息提示,比如linux可以使用strerror(errno)获取错误信息,WSAGetLastError()虽然可以取到错误码,但还要去查,有个FORmatmessage函数试了下,有些可以获取有些不能--!