服务器是完成端口模型。
如果服务器要传几K的数据给客户端。 直接 WSASend就可以了 。然后客户端 recv 收到就完成了。我的问题来了。问题1: 如果要传几十K的数据,我在局域网试了下,客户端也可以一次全部recv(没有修改过发送或者接收缓冲区)。 这好像和我网上看到的说法相悖。
网上一般说默认缓冲区是8K。 那么我的数据怎么会一次都可以recv到。问题2: 如果数据大,要分包传,我在网上看到说服务器可以用send阻塞循环传 或者 分包传。能不能给个最好的思路?问题3: 我用的是 AccptEx 这个函数来异步接收到来的客户连接请求。 但是我处理不好恶意攻击(就是客户只连接不发数据)我是用队列管理 完成键 和 重叠结构。 自己看自己的程序都复杂。 希望好心人能帮忙解答下我的问题,能说多少说多少。或者能留下QQ 我加QQ请教下您。绝对不会耽误太多时间。 或者谁有这方面好的说明文档或者网址都可以发出来。 分不够再加。 谢谢了。 2天结账。
如果服务器要传几K的数据给客户端。 直接 WSASend就可以了 。然后客户端 recv 收到就完成了。我的问题来了。问题1: 如果要传几十K的数据,我在局域网试了下,客户端也可以一次全部recv(没有修改过发送或者接收缓冲区)。 这好像和我网上看到的说法相悖。
网上一般说默认缓冲区是8K。 那么我的数据怎么会一次都可以recv到。问题2: 如果数据大,要分包传,我在网上看到说服务器可以用send阻塞循环传 或者 分包传。能不能给个最好的思路?问题3: 我用的是 AccptEx 这个函数来异步接收到来的客户连接请求。 但是我处理不好恶意攻击(就是客户只连接不发数据)我是用队列管理 完成键 和 重叠结构。 自己看自己的程序都复杂。 希望好心人能帮忙解答下我的问题,能说多少说多少。或者能留下QQ 我加QQ请教下您。绝对不会耽误太多时间。 或者谁有这方面好的说明文档或者网址都可以发出来。 分不够再加。 谢谢了。 2天结账。
SOCKET hSocket,
HANDLE hFile,
DWORD nNumberOfBytesToWrite,
DWORD nNumberOfBytesPerSend,
LPOVERLAPPED lpOverlapped,
LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers,
DWORD dwFlags
);
你的bufSize设的太大了,通常1024 ~ 1024 * 3个人意见~
http://www.joyvc.cn/NetworkAndCommunication/NetworkAndCommunicationGroup00221.html
如果服务器发送的数据很小(比如几百字节),客户端就可以正确的返回接收到的字节数。以上都是测试结果
怎么可能? #define DATA_BUFSIZE 1024
CHAR Buffer[DATA_BUFSIZE];
pSockInfo->DataBuf.buf = Buffer;
pSockInfo->DataBuf.len = DATA_BUFSIZE;
WSASend(pSockInfo->Socket, &(pSockInfo->DataBuf), 1, &SendBytes, 0,
&(pSockInfo->Overlapped), NULL);
你把这个DATA_BUFSIZE设成 1024 它能一次发几十K?
CompletionPort, //完成端口对象
&BytesTransferred, //接收字节数
(LPDWORD)&pSOCKINFO, //单socket数据结构
&lpOverlapped, //OVERLAPPED
INFINITE);打印BytesTransferred,这个是发出的字节,看它是多少,
另外: 50K = 50 * 1024;
CHAR Buffer[DATA_BUFSIZE];
pSockInfo->DataBuf.buf = Buffer;
pSockInfo->DataBuf.len = DATA_BUFSIZE;
WSASend(pSockInfo->Socket, &(pSockInfo->DataBuf), 1, &SendBytes, 0,
&(pSockInfo->Overlapped), NULL);
程序确实是这样的。DATA_BUFSIZE = 1024 SendBytes = 1024*50 =50k 测试发现一次WSASend ,GetQueuedCompletionStatus() 会返回, 第二个参数返回值就等于50k 参看msdn 表示发送了50k数据
但是客户端int ret = recv() 测试结果ret=0 。。 谁能告诉我为什么啊。我晕了。是局域网测试的。
谢谢你的回答。感觉有点用。。但是我是局域网,难道阻塞recv等不到完整的50k数据,还非要返回0表示数据不完整?
阻塞recv应该不会只等待一下下把?
DWORD WINAPI WorkerThread(LPVOID CompletionPortID)
{
HANDLE CompletionPort = (HANDLE)CompletionPortID;
DWORD BytesTransferred;
SOCKINFO* pSOCKINFO;
DWORD RecvBytes;
DWORD Flags= 0;
OVERLAPPED* lpOverlapped;
while(TRUE)
{
if (GetQueuedCompletionStatus(
CompletionPort, //完成端口对象
&BytesTransferred, //接收字节数
(LPDWORD)&pSOCKINFO, //单socket数据结构
&lpOverlapped, //OVERLAPPED
INFINITE) == 0)
{
GXOnClose(pSOCKINFO);//自定义函数
::SendMessage(g_hWnd, UM_SOCKET, 0, LPARAM("GetQueuedCompletionStatus错误错误"));
continue;
}
if (BytesTransferred == 0)
{
GXOnClose(pSOCKINFO);
::SendMessage(g_hWnd, UM_SOCKET, 0, LPARAM("BytesTransferred == 0"));
continue;
}
if (!OnRead(pSOCKINFO, BytesTransferred))//自定义函数
{
GXOnClose(pSOCKINFO);
::SendMessage(g_hWnd, UM_SOCKET, 0, LPARAM("OnRead函数过程发生错误"));
continue;
}
if (WSARecv(pSOCKINFO->Socket, &(pSOCKINFO->DataBuf), 1, &RecvBytes, &Flags,
&(pSOCKINFO->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
AfxMessageBox("WSARecv发生严重错误!!");
return 1;
}
}
}
}
只是接收,参考<Windows网络编程第二版 中文版>第八章
源码目录: Windows网络编程第二版 中文版\原码\Chapter08\IOcmplt