我在client程序中同时使用TCP和UDP协议,首先是建立一个TCP的连接,然后用同样的端口打开一个UDP的端口,等待接收数据,我用的 select,可是接受不到数据,有时候能够接受,请问是什么原因,谁能帮忙高分相送HRESULT tcp_client::connect(const char *host_name, unsigned short port)
{
WORD wVersionRequested = MAKEWORD(2,2);
WSADATA wsaData; HRESULT nRet = WSAStartup(wVersionRequested, &wsaData); if (wsaData.wVersion != wVersionRequested)
{
netmsg("Wrong version of Winsock");
return EXIT_FAILURE;
}
LPHOSTENT he = gethostbyname(host_name); if (he == NULL)
{
netmsg("Error in gethostbyname()");
return EXIT_FAILURE;
} m_sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (m_sockfd == INVALID_SOCKET)
{
netmsg("Error on call to socket()");
return EXIT_FAILURE;
} SOCKADDR_IN their_addr; their_addr.sin_family = AF_INET;
their_addr.sin_addr = *((LPIN_ADDR)*he->h_addr_list); their_addr.sin_port = htons(port); nRet = ::connect(m_sockfd, (LPSOCKADDR)&their_addr, sizeof(struct sockaddr)); if (nRet == SOCKET_ERROR)
{
netmsg("Error on connect");
return EXIT_FAILURE;
}
#ifdef USE_UDP
if(FAILED(connectUDP(host_name,port) ))
{
netmsg("Error on connect()");
return EXIT_FAILURE;
}
#endif
return nRet;
}HRESULT tcp_client::connectUDP(const char *host_name, unsigned short port)
{
int ret ;
SOCKADDR_IN local ;// myselfhost;
int namelen = sizeof(local);
//struct sockaddr_in
ret = getsockname(m_sockfd, (struct sockaddr*)&local, &namelen) ;
if(SOCKET_ERROR == ret)
{
netmsg("error in getsockname") ; return EXIT_FAILURE ;
}
/*
myselfhost.sin_family = AF_INET ;
myselfhost.sin_addr.s_addr = htonl(INADDR_ANY) ;
myselfhost.sin_port = local.sin_port ;// htons(port);
*/ m_udpfd = socket(AF_INET, SOCK_DGRAM, 0);
if (m_udpfd == INVALID_SOCKET)
{
netmsg("udp Error on call to socket");
return EXIT_FAILURE;
}
if((ret = bind(m_udpfd, (SOCKADDR*)&local,sizeof(local)))==SOCKET_ERROR)
{
netmsg("Error on UDP bind");
return EXIT_FAILURE;
}
return ret ;
}
HRESULT tcp_client::recv(char *data, int len)
{
if (!data)
{
return EXIT_FAILURE;
}
#ifdef USE_UDP
int max_fd ;
int hr = 0;
fd_set r_fdset ;
struct timeval timeval = {1,0};
RE_READ:
FD_ZERO(&r_fdset) ;
FD_SET(m_sockfd, &r_fdset) ;
FD_SET(m_udpfd, &r_fdset) ; max_fd = max(m_sockfd, m_udpfd) ; int ret = select (max_fd+1, &r_fdset, NULL,NULL, &timeval) ;
switch(ret)
{
case 0 :
goto RE_READ ;
case -1:
break ;
default:
if(FD_ISSET(m_sockfd,&r_fdset))
{
hr = ::recv(m_sockfd, data, len, 0);
}
else if(FD_ISSET(m_udpfd, &r_fdset) )
{
/*检查数据是否是来自我们的gameserver*/
hr = ::recv(m_udpfd, data, len, 0) ;
if(0==hr)
goto RE_READ ;
}
}
return hr ;
#else
//HRESULT hr = ::recv(m_sockfd, data, len, 0);
int hr = ::recv(m_sockfd, data, len, 0);
if (hr == SOCKET_ERROR)
{
return -1 ;
}
return hr ;
#endif
}
{
WORD wVersionRequested = MAKEWORD(2,2);
WSADATA wsaData; HRESULT nRet = WSAStartup(wVersionRequested, &wsaData); if (wsaData.wVersion != wVersionRequested)
{
netmsg("Wrong version of Winsock");
return EXIT_FAILURE;
}
LPHOSTENT he = gethostbyname(host_name); if (he == NULL)
{
netmsg("Error in gethostbyname()");
return EXIT_FAILURE;
} m_sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (m_sockfd == INVALID_SOCKET)
{
netmsg("Error on call to socket()");
return EXIT_FAILURE;
} SOCKADDR_IN their_addr; their_addr.sin_family = AF_INET;
their_addr.sin_addr = *((LPIN_ADDR)*he->h_addr_list); their_addr.sin_port = htons(port); nRet = ::connect(m_sockfd, (LPSOCKADDR)&their_addr, sizeof(struct sockaddr)); if (nRet == SOCKET_ERROR)
{
netmsg("Error on connect");
return EXIT_FAILURE;
}
#ifdef USE_UDP
if(FAILED(connectUDP(host_name,port) ))
{
netmsg("Error on connect()");
return EXIT_FAILURE;
}
#endif
return nRet;
}HRESULT tcp_client::connectUDP(const char *host_name, unsigned short port)
{
int ret ;
SOCKADDR_IN local ;// myselfhost;
int namelen = sizeof(local);
//struct sockaddr_in
ret = getsockname(m_sockfd, (struct sockaddr*)&local, &namelen) ;
if(SOCKET_ERROR == ret)
{
netmsg("error in getsockname") ; return EXIT_FAILURE ;
}
/*
myselfhost.sin_family = AF_INET ;
myselfhost.sin_addr.s_addr = htonl(INADDR_ANY) ;
myselfhost.sin_port = local.sin_port ;// htons(port);
*/ m_udpfd = socket(AF_INET, SOCK_DGRAM, 0);
if (m_udpfd == INVALID_SOCKET)
{
netmsg("udp Error on call to socket");
return EXIT_FAILURE;
}
if((ret = bind(m_udpfd, (SOCKADDR*)&local,sizeof(local)))==SOCKET_ERROR)
{
netmsg("Error on UDP bind");
return EXIT_FAILURE;
}
return ret ;
}
HRESULT tcp_client::recv(char *data, int len)
{
if (!data)
{
return EXIT_FAILURE;
}
#ifdef USE_UDP
int max_fd ;
int hr = 0;
fd_set r_fdset ;
struct timeval timeval = {1,0};
RE_READ:
FD_ZERO(&r_fdset) ;
FD_SET(m_sockfd, &r_fdset) ;
FD_SET(m_udpfd, &r_fdset) ; max_fd = max(m_sockfd, m_udpfd) ; int ret = select (max_fd+1, &r_fdset, NULL,NULL, &timeval) ;
switch(ret)
{
case 0 :
goto RE_READ ;
case -1:
break ;
default:
if(FD_ISSET(m_sockfd,&r_fdset))
{
hr = ::recv(m_sockfd, data, len, 0);
}
else if(FD_ISSET(m_udpfd, &r_fdset) )
{
/*检查数据是否是来自我们的gameserver*/
hr = ::recv(m_udpfd, data, len, 0) ;
if(0==hr)
goto RE_READ ;
}
}
return hr ;
#else
//HRESULT hr = ::recv(m_sockfd, data, len, 0);
int hr = ::recv(m_sockfd, data, len, 0);
if (hr == SOCKET_ERROR)
{
return -1 ;
}
return hr ;
#endif
}
解决方案 »
- 头都大了,f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) :
- 求助:各位大哥,俩帮我看看这几个 com 问题,好吗?谢谢!
- VC初学者应该先学什么?
- 最近要写个通过网闸的程序,可一直搞不清网闸到底是个什么东西,有知道的吗?
- 求一个能在 组合框 中选择图标的源程序!!!!!!!!谢谢
- 技术问题:怎样使上海的房价降下来???
- 关于dll程序中include “afx.h”失败的问题
- 有关构造函数的问题,求教!谢谢先了!
- 高手,请问两个局域网内的两台机器之间利用其各自的内网IP如何进行TCP通信?
- Direct3D 11 支持ActiveX控件吗?
- 怎样在VC中调用中断????????????最好有例子
- 怎样把系统自动弹出的MESSAGE BOX屏蔽掉,大家说说.
else if(FD_ISSET(m_udpfd, &r_fdset) )
{
/*检查数据是否是来自我们的gameserver*/
hr = ::recv(m_udpfd, data, len, 0) ;
if(0==hr)
goto RE_READ ;
}
你的m_udpfd没有connect不能用recv只能用recvfrom;
因为我们的winsock是建立在协议层次的上一层,
SOCKET---- WINSOCK.DLL----TCP /IP and so on
怎么可能呢!你说一会可以用,一会又不可以用,难道经常换机调试吗!
其实你开两个不同的端口,在自己机上调试就可以了。