我在写一个数据交换系统,winsocket,阻塞模式。整个流程大概是这样,我的客户端开启一个线程,然后发送一定量的数据给服务器,send发送完返回后,马上closesocket(),然后客户端的线程退出。
服务器端的接收流程大概是:接收户端发来的头,知道客户端发送数据的长度,为len,开辟len的buffer,然后while循环读取len个字节。
这个过程中,服务器recv一旦返回0,则表明客户端发送数据结束(因为客户端发送完后closesocket导致服务器端recv返回0),或者recv返回-1出错。现在的情况是,服务器端没接收够len长度的数据就跳出while了,并且疑惑的是,recv是返回0,而WSAGetlastError返回的错误码为10014,几次测试均返回10014。困惑中。向论坛里的前辈请教了!
服务器端的接收流程大概是:接收户端发来的头,知道客户端发送数据的长度,为len,开辟len的buffer,然后while循环读取len个字节。
这个过程中,服务器recv一旦返回0,则表明客户端发送数据结束(因为客户端发送完后closesocket导致服务器端recv返回0),或者recv返回-1出错。现在的情况是,服务器端没接收够len长度的数据就跳出while了,并且疑惑的是,recv是返回0,而WSAGetlastError返回的错误码为10014,几次测试均返回10014。困惑中。向论坛里的前辈请教了!
The buf parameter is not completely contained in a valid part of the user address space.最好贴一下代码
客户端代码,一个独立的发送数据线程,发完数据马上关socket,退出线程,服务器端recv应该返回0int AddShareThread::Run()
{
strcpy(szServerIP,"192.168.0.93");
uServerPort = 5590; //连接服务器
sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(szServerIP);
server_addr.sin_port = htons(uServerPort); SOCKET client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if ( client == INVALID_SOCKET )
{
//出错处理,返回错误码
return -1;
}
int nResult = connect(client,(SOCKADDR*)&server_addr,sizeof(server_addr));
if ( nResult == SOCKET_ERROR )
{
return -2;
} bool flag =1;
setsockopt( client, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag) ); CString szShareXml = GetFileXml(szPathArray);
char *xmlBuffer = new char[szShareXml.GetLength()*2];
memset(xmlBuffer,0,szShareXml.GetLength()*2);
strcpy(xmlBuffer,(char *)szShareXml.GetBuffer()); //发送请求头
Package p;
p.request = UPDATE;
p.len = strlen(xmlBuffer) + 1;
send(client,(char*)&p,sizeof(p),0); //发送数据给服务器
flag = 0;
setsockopt( client, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag) );
int nSends = 0;
nSends = send(client,xmlBuffer,strlen(xmlBuffer)+1,0); //如果这里数据还在socket的缓冲区
closesocket(client); //这里的应该会把所有数据发送出去吧?
delete []xmlBuffer;
return 0; //closesocket后,线程马上返回会不会危险?比如数据没发完就中断了?
//return CWinThread::Run();
}
服务器端读数据代码,服务器while接收数据,recv返回0表示客户端发送完成,-1出错,另外处理int read_package(SOCKET s, void *buf, int len)
{
int nBytes = 0;
int64 nCount = 0;
char *temp = (char*)buf; while ( len>0 )
{
nBytes = recv(s,temp,len,0); if ( nBytes <= 0 ) //有时,这里返回的nBytes为0,但是,错误码却为10014
break; nCount += nBytes;
temp += nCount;
len -= nBytes;
} return nCount;
}
上面的代码是服务器端读指定长度代码的一个函数,recv返回时,WSAGetlastError会报10014。
这个函数是,我传入一个socket和一块在堆上申请的buffer,传入buffer的长度,然后读数据,返回时,判断ncount == len 的话为读取正确,不等则为失败。我今晚测试十几次,都是报10014的错!!!
应该是temp += nBytes;
是的,脑袋糊了len -= nBytes;temp += nBytes;