读书人

关于Socket中TCP传输时的缓冲有关问题

发布时间: 2012-01-05 22:36:54 作者: rapoo

关于Socket中TCP传输时的缓冲问题。
才学习Socket编程,碰到这样一个问题:(描述有点长,但较详细,问题也简单)
我写了一个基于C/S模型的小程序,本始是仿写的一个聊天程序,服务器与客户端都是一个基于Dialog的程序,把聊天的内容显示在一个CListBox控件中。如果像QQ一样互聊的话没有什么问题,今天突想要是有很多数据要发送,比如在服务器上打开一个txt文件,然后再把内容给客户端,根据传输的原理应该没有什么问题,所以我就写了几行代码实现这样的一个功能。
实现原理是这样的,在服务器端,用fstream打开文件,用getline读文件,只要文件没有结束,就一直读下去,读一行,发送一行。客户端只负责接收并显示就可以了。运行程序的时候发现会出错,只能传送txt文件的前一两行到客户端。其它的传不了,但是如果服务器在调试状态下,却可以发送所有数据,后为发现是服务器发送数据过快,客户端读太慢引起的错误。

这是我发送线程处理代码:
DWORD WINAPI SendThreadProc( LPVOID lpParameter )
{
SOCKET sock=(SOCKET)lpParameter;
//打开文件
fstream ofs( "E:\\Program\\VC\\NetWork_Program\\SortMessage_S\\ReadMe.txt ");
int ret;
while(!ofs.eof ()) //文件没有结束就一直发送
{
//把文件内容读在g_strSend中。
if(getline (ofs,g_strSend, '\n '))
{
ret=send(sock,g_strSend.c_str(),g_strSend.size(),0);
if(SOCKET_ERROR==ret)
{
closesocket(sock);
AfxMessageBox( "服务器发送数据失败 ");
return -1;
}
//清除g_strSend同缓存。
g_strSend.erase(g_strSend.begin(),g_strSend.end());
}
}
return 0;
}

这是客户端接收信息的线程代码:
DWORD WINAPI RecvThreadProc( LPVOID lpParameter )
{
SOCKET sock=(SOCKET)lpParameter;

char recvBuff[256];
//发送数据
while(TRUE)
{
intret=recv(sock,recvBuff,256,0);
//在这里使用AfxMessageBox查看运行时每次接收数据的大小,因为在调试状态下是正确的,
char ch[5];
sprintf (ch, "%d ",ret);
AfxMessageBox (ch);
if(ret==SOCKET_ERROR)
{
AfxMessageBox( "客户端接收数据错误 ");
closesocket(sock);
return -1;
}
else if(ret==0)
{
AfxMessageBox( "服务器已经关闭 ");
closesocket(sock);
return -1;
}
else
recvBuff[ret]= '\0 ';//记得将recvBuff[ret]最后一个设为0,表示接收的字符串结束,//因为接收成功则会返回所以得的字符数
//这里把接收buff的数据放到一个全局的string类型变量中,g_strRecv里面就是所有的数据,将用于显示。
g_strRecv=recvBuff;
//这时清0接收缓冲区,用与下一个接收。
memset(recvBuff,0,sizeof(recvBuff));
}

return 0;
}
如果直接运行服务器与客户端程序,发现接收方的ret会超过recvBuff的大小,第一次读取时ret为72,第二次读取时ret就为256了,以后再读的话ret就为-1了,好像是recvBuff已经溢出了一样。但是在服务器程序为调试的状态下,客户端的ret第一次也是72,但是后面的读取都不会大于100,总是小于256的,所以能传送全部的数据。
所以我认为可能是在运行模式下,发送的数据太快,接收端来不及处理,因为调试的时候客户端有更多的时间进行处理,但这与Tcp的滑动窗口流量控制的理论相矛盾,所以问一下大家是怎么回事?怎么处理?谢谢!

[解决办法]
我觉得因为太快你的缓冲区被赛满了.所以就丢掉了.接收方后来就收不到后来的.
[解决办法]
不要乱说

intret=recv(sock,recvBuff,256,0);
//在这里使用AfxMessageBox查看运行时每次接收数据的大小,因为在调试状态下是

这里有一个bug
应该是255



[解决办法]
使用异步

读书人网 >VC/MFC

热点推荐