【发布时间】: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。