在 C++ 中的 UDP 套接字编程中获取“传输端点未连接”
Posted
技术标签:
【中文标题】在 C++ 中的 UDP 套接字编程中获取“传输端点未连接”【英文标题】:Getting "Transport endpoint is not connected" in UDP socket programming in C++ 【发布时间】:2012-04-12 07:04:13 【问题描述】:我在 UDP 服务器程序中收到 Transport endpoint is not connected
错误,而我正在尝试
通过shutdown(m_ReceiveSocketId, SHUT_RDWR);
关闭套接字
以下是我的代码 sn-p:
bool UDPSocket::receiveMessage()
struct sockaddr_in serverAddr; //Information about the server
struct hostent *hostp; // Information about this device
char buffer[BUFFERSIZE]; // Buffer to store incoming message
int serverlen; // to store server address length
//Open a datagram Socket
if((m_ReceiveSocketId = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
Utility_SingleTon::printLog(LOG_ERROR,"(%s %s %d) UDP Client - socket() error",__FILE__,__func__, __LINE__);
pthread_exit(NULL);
return false;
//Configure Server Address.
//set family and port
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(m_ListeningPort);
if (bind(m_ReceiveSocketId, (struct sockaddr *) &serverAddr,sizeof(struct sockaddr_in)) < 0 )
Utility_SingleTon::printLog(LOG_ERROR,"(%s %s %d) UDP Client- Socket Bind error=%s",__FILE__,__func__, __LINE__,strerror(errno));
pthread_exit(NULL);
return false;
//TODO Re-Route Mechanism.
if((serverAddr.sin_addr.s_addr = inet_addr(m_ServerIPStr.c_str())) == (unsigned long)INADDR_NONE)
/* Use the gethostbyname() function to retrieve */
/* the address of the host server if the system */
/* passed the host name of the server as a parameter. */
/************************************************/
/* get server address */
hostp = gethostbyname(m_ServerIPStr.c_str());
if(hostp == (struct hostent *)NULL)
/* h_errno is usually defined */
/* in netdb.h */
Utility_SingleTon::printLog(LOG_ERROR,"%s %d %s %s %d", "Host Not found", h_errno,__FILE__,__func__, __LINE__);
pthread_exit(NULL);
return false;
memcpy(&serverAddr.sin_addr, hostp->h_addr, sizeof(serverAddr.sin_addr));
serverlen = (int )sizeof(serverAddr);
// Loop and listen for incoming message
while(m_RecevieFlag)
int receivedByte = 0;
memset(buffer, 0, BUFFERSIZE);
//receive data from the server
receivedByte = recvfrom(m_ReceiveSocketId, buffer, BUFFERSIZE, 0, (struct sockaddr *)&serverAddr, (socklen_t*)&serverlen);
if(receivedByte == -1)
Utility_SingleTon::printLog(LOG_ERROR,"[%s:%d#%s] UDP Client - receive error",__FILE__,__LINE__,__func__);
close(m_ReceiveSocketId);
pthread_exit(NULL);
return false;
else if(receivedByte > 0)
string rMesg;
rMesg.erase();
for(int loop = 0; loop < receivedByte; loop++)
rMesg.append(1, buffer[loop]);
Utility_SingleTon::printLog(LOG_DEBUG,"[%s:%d#%s] received message=%d",__FILE__,__LINE__,__func__, rMesg.length());
QOMManager_SingleTon::getInstance()->setReceivedMessage(rMesg);
raise(SIGUSR1);
close(m_ReceiveSocketId);
pthread_exit(NULL);
return true;
任何帮助将不胜感激。 谢谢尤维。
【问题讨论】:
你不应该在调用bind
之前设置serverAddr.sin_addr
吗?另外,你从不在任何地方打电话给shutdown
?
shutdown
在类的析构函数中。关于绑定我不这么认为..如果我在serverAddr.sin_addr
之后使用bind
则不起作用
如果shutdown
的调用在析构函数中,那么大多数情况下你不是已经关闭了套接字吗?
receiveMessage
是一个线程函数,如果我不调用shutdown
则执行卡在recvfrom
或侦听模式。所以要退出套接字的侦听模式,我使用了@ 987654334@。并在recvfrom
.. 之后继续执行。
我自己并没有经常使用 UDP 套接字,但是快速的 Google 搜索表明 shutdown
不应该用于 UDP 套接字。 recvfrom
阻塞,因为套接字阻塞,要么使套接字非阻塞,要么使用标志 MSG_DONTWAIT
到 recvfrom
。
【参考方案1】:
您不需要为 UDP 套接字调用 shutdown()。从手册页:
The shutdown() call causes all or part of a full-duplex connection on the socket
associated with sockfd to be shut down.
如果您在 UDP 套接字上调用 shutdown(),它将返回 ENOTCONN (指定的套接字未连接)因为 UDP 是无连接协议。
您需要做的就是关闭套接字并将套接字设置为 INVALID_SOCKET。然后在你的析构函数中检查套接字在关闭之前是否已经设置为 INVALID_SOCKET 。
【讨论】:
如果我这样做了,那么线程的执行会卡在recvfrom
并且线程永远不会退出。
@Yuvi:如果关闭套接字,recvfrom() 应该返回 ENOTSOCK。这没有发生吗?
是的,但是如何摆脱 recvfrom
阻塞套接字,你有任何参考链接吗?
我认为您需要发布更多代码。您是否试图通过在不同的线程中执行某些操作来退出 recvfrom() ?如果不是,那么您可能希望使您的套接字非阻塞和/或使用 select() 来检查套接字上可用的数据。关于 select() 和其他 tcp 细节的细节在这里:beej.us/guide/bgnet/output/html/singlepage/bgnet.html#select以上是关于在 C++ 中的 UDP 套接字编程中获取“传输端点未连接”的主要内容,如果未能解决你的问题,请参考以下文章