新手问题,我用CSocket和一个服务器连接,但是有时服务器端发数据过来,我CSocket->OnReceive又没有响应。我想在CSocket->OnReceive在过

时间:2021-04-27 16:57:11
1、不知道要检测CSocket哪些状态?
2、用什么函数检检测?

18 个解决方案

#1


用定时器

#2


如果你用循环发送数据的 话,建议每次循环都要休眠一下(用Sleep(100))

#3


hehe……我是客户端

#4


同时,也知道服务器端给发过来的数据的大小,

能不能在CSocket->OnReceive下,循环调用CSocket->Receive把数据收完;

还是先收一部分数据,让系统自己触发CSocket->OnReceive,再收一部分?

#5


实在不行。可以:
在nRead=Receive(rBuf,SEND_BYTES);与GetLastError之后调用

AsyncSelect( FD_READ | FD_WRITE | FD_CLOSE );

#6


你没有调用CAsyncSocket::AsyncSelect()吧?

#7


呵呵……没有,我还不知道那个函数是什么用途啊

#8


还有什么时候调用GetLastError()和CAsyncSocket::AsyncSelect()?

#9


接收方的tcp层有待收数据时,会触发ON_RECEIVE事件,即触发CSocket->OnReceive,此时是没有接收任何数据的,真正的接收数据是CSocket->Receive完成的

#10


可能没有把问题说清楚。比如服务器一下要发131072数据给我,而我在CSocket->OnReceive时调用CSocket->Receive只是收1024,其余的让系统自己再触发CSocket->OnReceive,我再收1024,这样循环把数据接收完。

这样的数据接收是否正确?

#11


c0der() :我没有调用CAsyncSocket::AsyncSelect(),这样会有什么后果?

#12


你还是用循环接收的方法吧。
一般TCP协议都是这么做的。

#13


laa(阿呆) ( ) 信誉:100  2003-02-20 08:03:00  得分:0  
 
  可能没有把问题说清楚。比如服务器一下要发131072数据给我,而我在CSocket->OnReceive时调用CSocket->Receive只是收1024,其余的让系统自己再触发CSocket->OnReceive,我再收1024,这样循环把数据接收完。

这样的数据接收是否正确?

以下是我的理解,不知对不对:
以下指是描述意思,不拘细节:
当131072数据被客户端接收时,存在客户端的接收缓冲区中,
系统发现接收缓冲区有了新数据,可以被客户端程序接收,
于是它查看用户是否想得到“有新数据可接受”的消息通知,
如果,用户想得到这一通知,就通知该用户。通知方式是OnRecv被调用。
用户此时可以接收数据到自己指定的内存。
那末,系统如何知道用户想不想得到该通知呢?如果用户调用了
AsyncSelect( FD_READ);系统就知道用户想的到该通知。
而这一步是异步套接字类构造时自动做了的。

但是,如果,客户端在一次OnRecv中只Recv了1024,剩下的数据仍在接受缓冲区中,在下一次服务端发送131072数据(实际上发不了那末多)时,系统发现又接受了新数据,会再次调用OnRecv.
而在此之前,系统不会再自动检查接受缓冲区是否还有数据待接受,也就不会调用OnRecv.
这时,
一种方法是在OnRecv中不断调用Recv,但是缺点是就不再异步了,因为可能接受指定的长度的数据有的Recv会阻塞住,因为数据未达到那莫长。
一种方法是WSAIoctl以FIONREAD参数查看接受缓冲区内还有多少数据可接受,之后只接受该长度的数据。但缺点是有时数据长度可能不正确。
一种方法是自行调用AsyncSelect( FD_READ);命令系统这时检查接受缓冲区内是否还有数据,如果有,系统又会再调用OnRecv。这里注意的是异步套接字在调用AsyncSelect时一次应将所有要接受的事件类型同时设置。因为后一次调用时会替换原来的设置。所以调用
AsyncSelect( FD_READ | FD_WRITE | FD_CLOSE );

也不知对不对,自己试试。
  
 

#14


热切关注中
我用Recv接受数据时出现过一个奇怪的错误:
我是用循环一次接受完所有数据。时而会出现死机或好长时间无响应(5-10分钟)

不知为何?

#15


laa(阿呆):....其余的让系统自己再触发CSocket->OnReceive,我再收1024,这样循环把数据接收完...,

不能再触发CSocket->OnReceive,你为何不再CSocket->OnReceive里调用CSocket->Receive把剩下的数据接收完?

#16


gz

#17


你的服务器端可以修改的话,就先把要传多少用4byte发到客户端,这样循环不就好办了吗?

#18


我还是不明白,为什么我在debug里面看,为什么我的OnReceive始终就没有进去.
客户端发了信息了,但是我的程序就是没有运行到OnReceive中去了
到底怎么回事哑!!!!

#1


用定时器

#2


如果你用循环发送数据的 话,建议每次循环都要休眠一下(用Sleep(100))

#3


hehe……我是客户端

#4


同时,也知道服务器端给发过来的数据的大小,

能不能在CSocket->OnReceive下,循环调用CSocket->Receive把数据收完;

还是先收一部分数据,让系统自己触发CSocket->OnReceive,再收一部分?

#5


实在不行。可以:
在nRead=Receive(rBuf,SEND_BYTES);与GetLastError之后调用

AsyncSelect( FD_READ | FD_WRITE | FD_CLOSE );

#6


你没有调用CAsyncSocket::AsyncSelect()吧?

#7


呵呵……没有,我还不知道那个函数是什么用途啊

#8


还有什么时候调用GetLastError()和CAsyncSocket::AsyncSelect()?

#9


接收方的tcp层有待收数据时,会触发ON_RECEIVE事件,即触发CSocket->OnReceive,此时是没有接收任何数据的,真正的接收数据是CSocket->Receive完成的

#10


可能没有把问题说清楚。比如服务器一下要发131072数据给我,而我在CSocket->OnReceive时调用CSocket->Receive只是收1024,其余的让系统自己再触发CSocket->OnReceive,我再收1024,这样循环把数据接收完。

这样的数据接收是否正确?

#11


c0der() :我没有调用CAsyncSocket::AsyncSelect(),这样会有什么后果?

#12


你还是用循环接收的方法吧。
一般TCP协议都是这么做的。

#13


laa(阿呆) ( ) 信誉:100  2003-02-20 08:03:00  得分:0  
 
  可能没有把问题说清楚。比如服务器一下要发131072数据给我,而我在CSocket->OnReceive时调用CSocket->Receive只是收1024,其余的让系统自己再触发CSocket->OnReceive,我再收1024,这样循环把数据接收完。

这样的数据接收是否正确?

以下是我的理解,不知对不对:
以下指是描述意思,不拘细节:
当131072数据被客户端接收时,存在客户端的接收缓冲区中,
系统发现接收缓冲区有了新数据,可以被客户端程序接收,
于是它查看用户是否想得到“有新数据可接受”的消息通知,
如果,用户想得到这一通知,就通知该用户。通知方式是OnRecv被调用。
用户此时可以接收数据到自己指定的内存。
那末,系统如何知道用户想不想得到该通知呢?如果用户调用了
AsyncSelect( FD_READ);系统就知道用户想的到该通知。
而这一步是异步套接字类构造时自动做了的。

但是,如果,客户端在一次OnRecv中只Recv了1024,剩下的数据仍在接受缓冲区中,在下一次服务端发送131072数据(实际上发不了那末多)时,系统发现又接受了新数据,会再次调用OnRecv.
而在此之前,系统不会再自动检查接受缓冲区是否还有数据待接受,也就不会调用OnRecv.
这时,
一种方法是在OnRecv中不断调用Recv,但是缺点是就不再异步了,因为可能接受指定的长度的数据有的Recv会阻塞住,因为数据未达到那莫长。
一种方法是WSAIoctl以FIONREAD参数查看接受缓冲区内还有多少数据可接受,之后只接受该长度的数据。但缺点是有时数据长度可能不正确。
一种方法是自行调用AsyncSelect( FD_READ);命令系统这时检查接受缓冲区内是否还有数据,如果有,系统又会再调用OnRecv。这里注意的是异步套接字在调用AsyncSelect时一次应将所有要接受的事件类型同时设置。因为后一次调用时会替换原来的设置。所以调用
AsyncSelect( FD_READ | FD_WRITE | FD_CLOSE );

也不知对不对,自己试试。
  
 

#14


热切关注中
我用Recv接受数据时出现过一个奇怪的错误:
我是用循环一次接受完所有数据。时而会出现死机或好长时间无响应(5-10分钟)

不知为何?

#15


laa(阿呆):....其余的让系统自己再触发CSocket->OnReceive,我再收1024,这样循环把数据接收完...,

不能再触发CSocket->OnReceive,你为何不再CSocket->OnReceive里调用CSocket->Receive把剩下的数据接收完?

#16


gz

#17


你的服务器端可以修改的话,就先把要传多少用4byte发到客户端,这样循环不就好办了吗?

#18


我还是不明白,为什么我在debug里面看,为什么我的OnReceive始终就没有进去.
客户端发了信息了,但是我的程序就是没有运行到OnReceive中去了
到底怎么回事哑!!!!