socket编程,遇到很奇怪的问题,高分求教

autodesk 2007-06-15 10:24:18
本人使用socket编程,同步方式,服务器send次数大概为200多次,客户端接受200多次,次数相同,而且次序一致,发一次接受一次。但是运行十次大概有两次就要出错,其他几次都可以正确接受数据,为什么会这样?求教了
...全文
235 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
autodesk 2007-06-17
  • 打赏
  • 举报
回复
给分了
vividtower 2007-06-16
  • 打赏
  • 举报
回复
Sleep一下似乎不是很好,send如果可以合并就合并一下
autodesk 2007-06-15
  • 打赏
  • 举报
回复
多谢,我也正准备合并send,不过没有想到要sleep一下,试完给分
mudunke775 2007-06-15
  • 打赏
  • 举报
回复
简单,因为你send发送的间隔比较小,网卡会把多个send做为一个包同时发送,接受处理的时候就会出错。

处理方法:自己把多个send合为一个send。或者每个send后Sleep(10)
autodesk 2007-06-15
  • 打赏
  • 举报
回复
PF_INET和AF_INET的定义值是一样的,前者是协议族,后者是地址族,这个应该没有问题,我还想请教一下,send和recv在收发时的字节数有没有什么要求,必须一致吗,而且设定的字节数可以比实际传输的字节数大吗
ouyh12345 2007-06-15
  • 打赏
  • 举报
回复
1、服务端PF_INET和AF_INET是否要统一一下。
2、记录下服务端发包的目的地及发出的具体内容,同时记录客户端收到的内容,然后对照
autodesk 2007-06-15
  • 打赏
  • 举报
回复
发送端
WSADATA wsaData;
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
{
MessageBox(0,L"wsastartup error",L"xiaoxi",0);
return 1;
}
SOCKET mSocket;
mSocket=socket(PF_INET,SOCK_STREAM,0);
int bufsize=9000;

setsockopt(mSocket,SOL_SOCKET,SO_RCVBUF,(char *)&bufsize,sizeof(bufsize));
SOCKADDR_IN addr;
addr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addr.sin_family=AF_INET;
addr.sin_port=htons(5000);
if(bind(mSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR))==SOCKET_ERROR)
{
MessageBox(0,L"bind error",L"xiaoxi",0);
return 1;
}
if(listen(mSocket,5)<0)
{
MessageBox(0,L"listen error",L"xiaoxi",0);
return 1;
}
count=(char *)&countContact;
send(tSocket,count,4,0);
for(i=0;i<countContact;i++)
{
item=(pCAddin->v_contact)[i].GetFirstname();
send(tSocket,item.c_str(),32,0);
item=(pCAddin->v_contact)[i].GetSecondname();
send(tSocket,item.c_str(),32,0);
item=(pCAddin->v_contact)[i].GetCompany();
send(tSocket,item.c_str(),128,0);
item=(pCAddin->v_contact)[i].GetDepart();
send(tSocket,item.c_str(),64,0);
item=(pCAddin->v_contact)[i].GetJob();
send(tSocket,item.c_str(),32,0);
item=(pCAddin->v_contact)[i].GetBusinesscall(); send(tSocket,item.c_str(),32,0);
item=(pCAddin->v_contact)[i].GetBusinesscall2();
send(tSocket,item.c_str(),32,0);
item=(pCAddin->v_contact)[i].GetBusinessfaxcall();
send(tSocket,item.c_str(),32,0);
item=(pCAddin->v_contact)[i].GetBackcall();
send(tSocket,item.c_str(),32,0);
item=(pCAddin->v_contact)[i].GetCompanycall(); send(tSocket,item.c_str(),32,0);
item=(pCAddin->v_contact)[i].GetHomecall();
}
代码很长,只写出一部分,发送的循环send共有五个,和上面的代码类似,其中item是string类型。

接受段:
if(setsockopt(mSocket,SOL_SOCKET,SO_RCVBUF,(char *)&bufsize,sizeof(bufsize))<0)
{
::MessageBox(0,L"set socket opt error",L"xiaoxi",0);
return 1;
}
if(connect( mSocket,(SOCKADDR*)& addr,sizeof(SOCKADDR))<0)
{
int a=GetLastError();
::ofstream f;
f.open("e:\\testemailconnect.txt",ios::out);
f<<a<<endl;
f.close();
::MessageBox(0,L"connect error",L"xiaoxi",0);
return 1;
}


if(recv( mSocket,(char *)c,sizeof(unsigned long),0)<=0)
{
int a=GetLastError();
::MessageBox(0,L"recv count error",L"xiaoxi",0);
return 1;
}
if(recv( mSocket,(char *)c,sizeof(unsigned long),0)<=0)
{
int a=GetLastError();
::MessageBox(0,L"contact recv count error",L"xiaoxi",0);
return 1;
}
for(i=0;i<count;i++)
{
if(recv( mSocket,firstname,32,0)<=0)
{
::MessageBox(0,L"contact recv firstname error",L"xiaoxi",0);
return 1;
}
if(recv( mSocket,secondname,32,0)<=0)
{
::MessageBox(0,L"recv secondname error",L"xiaoxi",0);
return 1;
}
if(recv( mSocket,company,128,0)<=0)
{
::MessageBox(0,L"recv subject error",L"xiaoxi",0);
return 1;
}
if(recv( mSocket,department,64,0)<=0)
{
::MessageBox(0,L"recv department error",L"xiaoxi",0);
return 1;
}
if(recv( mSocket,job,32,0)<=0)
{
::MessageBox(0,L"recv job error",L"xiaoxi",0);
return 1;
}
if(recv( mSocket,business_call,32,0)<=0)
{
::MessageBox(0,L"recv businesscall error",L"xiaoxi",0);
return 1;
}
if(recv( mSocket,business2_call,32,0)<=0)
{
::MessageBox(0,L"recv business_call2 error",L"xiaoxi",0);
return 1;
}
if(recv( mSocket,businessfax_call,32,0)<=0)
{
::MessageBox(0,L"recv businessfaxcall error",L"xiaoxi",0);
return 1;
}
if(recv( mSocket,back_call,32,0)<=0)
{
::MessageBox(0,L"recv back_call error",L"xiaoxi",0);
return 1;
}
if(recv( mSocket,company_call,32,0)<=0)
{
::MessageBox(0,L"recv company_call error",L"xiaoxi",0);
return 1;
}
}
}
这里也是大概贴的一部分,写的太不简洁,还要改,我想问一下这样作有没有什么原则性的错误。会不会是因为send 和recv的字节数的问题呢?
ouyh12345 2007-06-15
  • 打赏
  • 举报
回复
tcp和udp在接收时都会做crc校验的,出错的概率比较小,绝对不会10中错1、2次。
看来问题应该出现在楼主的代码里。
贴出代码,主要是socket怎样初始化,怎样收发
autodesk 2007-06-15
  • 打赏
  • 举报
回复
关键是不报错,recv可以收到数据,但是收到的数据不正确,也就是说有时候是对的,有时候是错的
fantiyu 2007-06-15
  • 打赏
  • 举报
回复
发送包太小而且太连续的时候,系统底层就会在缓冲区里自动合并
貌似有个设置可以让它直接发送



-------------------------------------------------------
广告:VC/WinAPI 网络/多线程讨论 QQ群, 群号:41356711
ouyh12345 2007-06-15
  • 打赏
  • 举报
回复
先用WSAGetLastError看出错原因,再分析
autodesk 2007-06-15
  • 打赏
  • 举报
回复
先顶一下
suprwx 2007-06-15
  • 打赏
  • 举报
回复
是不是设定的发送数据长度大于数据的实际长度致导致读取到其他内存
Avoid 2007-06-15
  • 打赏
  • 举报
回复
建议send之前把string的内容用base64编码一下

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧