服务端给客户端不断地发10条数据,但服务端只发到一条,什么原因呢?

时间:2021-07-05 17:26:22
1、用CSocket 派生的类,在OnReceirve()中写收到的buf,但服务端发送连续发了10数据,客户端只收到1条,但如果是单步调试的话,就可收到尽量多的数据,我已经做了以下的设置,但还不行,不知道为什么?
int nNetTimeout=1000;//1秒
SetSockOpt(SO_SNDTIMEO,(char *)&nNetTimeout, sizeof(int));
//接收时限
SetSockOpt(SO_RCVTIMEO,(char *)&nNetTimeout, sizeof(int));
int nRecvBuf=32*1024;//设置为32K
SetSockOpt(SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));

2、同样,用多线程循环发送数据时,就会报错,CSOCKET是不支持多线程的吗?

13 个解决方案

#1


1.在OnReceive中,应该循环接收,直到没有数据为止。
2.CSocket在跨线程时有问题,主要原因是CSocket与SOCKET之间的映射是通过一个线程局部存储的MAP来实现的。

#2


那1条数据应该是10条的总和吧,服务端先发1条,客户端接受后返回一个应答信息,服务端受到应答就继续发,没收到就不发,这客户端样就可以1条1条接收了

#3


在服务器端的CONNECT消息处理中加上SetSockOpt(TCP_NODELAY,&b,sizeof(BOOL),IPPROTO_TCP)
这样就可以了。

#4


其中b是一个BOOL 型变量
CMySock *clskt=new CMySock(this);
BOOL b=0;
clskt->SetSockOpt(TCP_NODELAY,&b,sizeof(BOOL),IPPROTO_TCP);
CMySock *)wparam)->Accept(*clskt);

#5


DentistryDoctor(雅克医生<改行做程序员了>), 我发的数据不大,只有1K多一点,一下子就收完了,且我循环也试过了,还是不行啊?

 Caps77(厉兵秣马) 大侠,照你的说法,如果我一点按钮就循环发10个过去,在这代码里,怎样控制发一个,收应答一个,再发一个,再收应答一个呢?还有,我用客户端给服务器端发的时候,就可以一下子把10个信息发过去了,为何反过来就不行呢?

#6


CSocket我基本不用,SOCKET API只要在循环里调用send,再调用recv就行了

记得CSocket习惯上都会有两个函数,一个接收,一个发送,好像习惯上函数名都写成PendingReceive
或者PendingSend ,你只要循环调用这辆个函数就行

#7


我刚才就用Socket试了一下,对方发10条过来,收到的只是第一条,OnMessagePending()是程序有消息的时候处理的函数吧,还没有没有搞点,大侠救命。

#8


我以前用CSocket也遇到过,楼上说的都对,你自己仔细看看。

#9


客户端用链表。
再开线程从链表里一个包一个包的读。

#10


楼上的,能不能说详细点,或者给个例子,邮件:afd@netease.com谢谢。

#11


正常;
SOCKET默认并不是一有数据就马上返回让你RECV到的,因为这样效率不高;
大家都说CSOCKET不适合使用多线程;

#12


粘包?

#13


其实你收到的是10条,只不过其他9条信息都附加在第一条后面了。系统为了提高网络的利用率,会将几批数据打包成一个大包发送出去,你可以用SetSockOpt(TCP_NODELAY,&b,sizeofBOOL),IPPROTO_TCP)让它不打包,但这样会降低网络的利用率。这样肯定行的,你的问题我也碰到过,但现在解决了

#1


1.在OnReceive中,应该循环接收,直到没有数据为止。
2.CSocket在跨线程时有问题,主要原因是CSocket与SOCKET之间的映射是通过一个线程局部存储的MAP来实现的。

#2


那1条数据应该是10条的总和吧,服务端先发1条,客户端接受后返回一个应答信息,服务端受到应答就继续发,没收到就不发,这客户端样就可以1条1条接收了

#3


在服务器端的CONNECT消息处理中加上SetSockOpt(TCP_NODELAY,&b,sizeof(BOOL),IPPROTO_TCP)
这样就可以了。

#4


其中b是一个BOOL 型变量
CMySock *clskt=new CMySock(this);
BOOL b=0;
clskt->SetSockOpt(TCP_NODELAY,&b,sizeof(BOOL),IPPROTO_TCP);
CMySock *)wparam)->Accept(*clskt);

#5


DentistryDoctor(雅克医生<改行做程序员了>), 我发的数据不大,只有1K多一点,一下子就收完了,且我循环也试过了,还是不行啊?

 Caps77(厉兵秣马) 大侠,照你的说法,如果我一点按钮就循环发10个过去,在这代码里,怎样控制发一个,收应答一个,再发一个,再收应答一个呢?还有,我用客户端给服务器端发的时候,就可以一下子把10个信息发过去了,为何反过来就不行呢?

#6


CSocket我基本不用,SOCKET API只要在循环里调用send,再调用recv就行了

记得CSocket习惯上都会有两个函数,一个接收,一个发送,好像习惯上函数名都写成PendingReceive
或者PendingSend ,你只要循环调用这辆个函数就行

#7


我刚才就用Socket试了一下,对方发10条过来,收到的只是第一条,OnMessagePending()是程序有消息的时候处理的函数吧,还没有没有搞点,大侠救命。

#8


我以前用CSocket也遇到过,楼上说的都对,你自己仔细看看。

#9


客户端用链表。
再开线程从链表里一个包一个包的读。

#10


楼上的,能不能说详细点,或者给个例子,邮件:afd@netease.com谢谢。

#11


正常;
SOCKET默认并不是一有数据就马上返回让你RECV到的,因为这样效率不高;
大家都说CSOCKET不适合使用多线程;

#12


粘包?

#13


其实你收到的是10条,只不过其他9条信息都附加在第一条后面了。系统为了提高网络的利用率,会将几批数据打包成一个大包发送出去,你可以用SetSockOpt(TCP_NODELAY,&b,sizeofBOOL),IPPROTO_TCP)让它不打包,但这样会降低网络的利用率。这样肯定行的,你的问题我也碰到过,但现在解决了