问题 另一端发数据后就是接收不到
代码如下:socksvr = socket(AF_INET,SOCK_DGRAM,0);sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = INADDR_ANY;
addr.sin_port = 54321;if(::bind(socksvr,(const sockaddr*)&addr,sizeof(sockaddr_in)) == -1)
return FALSE;if(::WSARecv(sock,&wsaBuf,1,&dwByteTrans,&dwFlag,&overlapped,CompletionRoutine) == SOCKET_ERROR)
{
if(::WSAGetLastError() != WSA_IO_PENDING)
{
OnError();
return FALSE;
}
}
这样投递一个接收操作成功可为什么接受不到数据呢 ??我用如下方法便可正确接收 while(1)
{
int ll = 0;
ll = ::recvfrom(sock,data,100,0,(sockaddr*)&addr,&addrlen);
data[ll] = '\0';
....
}这是为什么啊 请高手指教
代码如下:socksvr = socket(AF_INET,SOCK_DGRAM,0);sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = INADDR_ANY;
addr.sin_port = 54321;if(::bind(socksvr,(const sockaddr*)&addr,sizeof(sockaddr_in)) == -1)
return FALSE;if(::WSARecv(sock,&wsaBuf,1,&dwByteTrans,&dwFlag,&overlapped,CompletionRoutine) == SOCKET_ERROR)
{
if(::WSAGetLastError() != WSA_IO_PENDING)
{
OnError();
return FALSE;
}
}
这样投递一个接收操作成功可为什么接受不到数据呢 ??我用如下方法便可正确接收 while(1)
{
int ll = 0;
ll = ::recvfrom(sock,data,100,0,(sockaddr*)&addr,&addrlen);
data[ll] = '\0';
....
}这是为什么啊 请高手指教
换成udp 形式的就是不行 郁闷啊
接收端:
socksvr = socket(AF_INET,SOCK_DGRAM,0);sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = INADDR_ANY;
addr.sin_port = 54321;if(::bind(socksvr,(const sockaddr*)&addr,sizeof(sockaddr_in)) == -1)
return FALSE;
if(::WSARecvFrom(sock,&wsaBuf,1,&dwByteTrans,&dwFlag,(sockaddr*)&addr,&fromlen,&overlapped,CompletionRoutine) == SOCKET_ERROR)
{
if(::WSAGetLastError() != WSA_IO_PENDING)
{
OnError(pRoutine);
return FALSE;
}
}
发送端:sockclt = socket(AF_INET,SOCK_DGRAM,0);
if(sockclt == SOCKET_ERROR)
{
AfxMessageBox("create socket error");
return;
}
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = INADDR_ANY;
addr.sin_port = 0;
nRet = bind(sockclt,(const sockaddr*)&addr,sizeof(sockaddr_in));
if(nRet == SOCKET_ERROR)
{
AfxMessageBox("bind error");
return;
}
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = inet_addr("接收端IP");
addr.sin_port = 54321;
while(1)
{
CString ss;
ss.Format("Thread:%d - send data times:%d\0",id,times);
int nRet = sendto(sockclt,ss,ss.GetLength(),0,(const sockaddr*)&addr,sizeof(sockaddr_in));
if(nRet == SOCKET_ERROR)
{
CString s;
s.Format("sendto error socket:%d",::WSAGetLastError());
pthis->m_list.InsertString(0,s);
}
if(sockclt == SOCKET_ERROR)
{
AfxMessageBox("create socket error");
return;
}
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = INADDR_ANY;
addr.sin_port = 0;
nRet = bind(sockclt,(const sockaddr*)&addr,sizeof(sockaddr_in));
if(nRet == SOCKET_ERROR)
{
AfxMessageBox("bind error");
return;
} //addr1 与addr是不同的地址结构,你弄混淆了,
// addr1是服务器地址结构,也就是接收数据的地址结构
// addr为本地client的地址结构,也就是你建立socket后
// 感兴趣的地址结构
addr1.sin_family = AF_INET;
addr1.sin_addr.S_un.S_addr = inet_addr("接收端IP");
addr1.sin_port = 54321;
while(1)
{
CString ss;
ss.Format("Thread:%d - send data times:%d\0",id,times);
int nRet = sendto(sockclt,ss,ss.GetLength(),0,(const sockaddr*)&addr1,sizeof(sockaddr_in));
if(nRet == SOCKET_ERROR)
{
CString s;
s.Format("sendto error socket:%d",::WSAGetLastError());
pthis->m_list.InsertString(0,s);
}
函数用对了吗?
当你while(1){recvfrom()}的时候是没有问题的因为你一直在接收
但是当你WSARecvFrom()的时候,有可能数据应该丢失了你才投递的
操作,而且如果缓冲区满,WSARecvFrom()投递一次后,在投递也会失败
socksvr = socket(AF_INET,SOCK_STREAM,0);
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = INADDR_ANY;
addr.sin_port = 54321;
if(::bind(socksvr,(const sockaddr*)&addr,sizeof(sockaddr_in)) == -1)
return FALSE;
if(::listen(socksvr,5) == -1)
return FALSE;
thrhandle = ::CreateThread(NULL,0,AcceptProc,this,0,NULL);
return TRUE;监听线程:
DWORD WINAPI AcceptProc(LPVOID lParam)
{
TestSvr* pSvr = (TestSvr*)lParam;
static int acceptnum = 0;
sockaddr_in addr;
int naddrlen = sizeof(sockaddr_in); while(TRUE)
{
SOCKET sock = ::accept(pSvr->socksvr,(sockaddr*)&addr,&naddrlen);
TRACE("");
CString s;
s.Format("新连接: %d",sock);
g_list->InsertString(0,s);
if(sock == SOCKET_ERROR)
{
CString s;
s.Format("错误: %d",::WSAGetLastError());
g_list->InsertString(0,s);
//return -1L;
continue;
} if(!pSvr->AddItem(sock,0,0)) //投递一个 WSARecv操作
{
AfxMessageBox("add socket error!");
}
}
return 0L;
}
BOOL AddItem(SOCKET sock,int type,LPARAM lParam)
{
.....
if(::WSARecv(sock,&wsaBuf,1,&dwByteTrans,&dwFlag,&overlapped,CompletionRoutine) == SOCKET_ERROR)
{
if(::WSAGetLastError() != WSA_IO_PENDING)
{
TRACE("PostRead WSARecv Error!");
return FALSE;
}
}
}然后客户端所发送的数据都能接收到 且做了回应
奇怪的是 我都没用 SleepEx 代码居然跑的好好的??
对UDP:建立服务端套接字
socksvr = ::WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED); sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = INADDR_ANY;
addr.sin_port = 54321; if(::bind(socksvr,(const sockaddr*)&addr,sizeof(sockaddr_in)) == -1)
return FALSE; AddItem(socksvr,1,this); //投递 WSARecvFromBOOL AddItem(....)
{
.....
if(type == 1)
{
int fromlen = sizeof(SOCKADDR_IN);
if(::WSARecvFrom(sock,&wsaBuf,1,&dwByteTrans,&dwFlag,(sockaddr*)&addr,&fromlen,&overlapped,CompletionRoutine) == SOCKET_ERROR)
{
if(::WSAGetLastError() != WSA_IO_PENDING)
{
return FALSE;
}
}
}
}加上 SleepEx //下面这样行吗??
DWORD WINAPI ThreadProc(LPVOID lParam)
{
while(g_bRun)
{
::SleepEx(50,TRUE);
}
}然后客户端向服务端发送数据就是收不到 奇怪对tcp 我都没调用到 SleepEx 它却跑的很好???
接着改了一下代码 终于可接收到UDP数据:
把对服务端套接字接收操作的投递放到ThreadProc中去DWORD WINAPI ThreadProc(LPVOID lParam)
{
while(g_bRun)
{
//只要投递过一次下句就不执行了
if(服务端套接字 没有投递过)
AddItem(sock,1,0);
::SleepEx(50,TRUE);
}
}
完成例程:
void CALLBACK CompletionRoutine(DWORD dwError,DWORD dwByteTrans,LPWSAOVERLAPPED lpOverlapped,DWORD dwFlag)
{
DWORD dwBtyeTrans = 0;
DWORD dwData = 0; ....... if(dwByteTrans == 0)
{
return;
}
if(dwError != 0 )
{
return;
} switch(所投递的操作类型)
{
case e_read:
{
//回应客户机...
if(是 tcp类型)
{
if(::WSARecv(sock,&wsaBuf,1,&dwByteTrans,&dwFlag,&overlapped,CompletionRoutine) == SOCKET_ERROR)
{
if(::WSAGetLastError() != WSA_IO_PENDING)
{
return;
}
}
}
if(是 udp类型)
{
int fromlen = sizeof(SOCKADDR_IN);
if(::WSARecvFrom(sock,&wsaBuf,1,&dwByteTrans,&dwFlag,(sockaddr*)&addr,&fromlen,&overlapped,CompletionRoutine) == SOCKET_ERROR)
{
if(::WSAGetLastError() != WSA_IO_PENDING)
{
return;
}
}
}
}
break;
case e_write:
{
//通知多少数据发送完毕...
}
break;
default:
return;
}
}出现上述这样的情况 请各位大侠帮小弟解释一下把