要解决的实际问题和具体要求:(以下均采用TCP/IP的方式)
1、要发送/接收的数据包可能比较大,有几十KB左右,但是为了传输安全,现在需要进行分包的传输,每一个包最大为1024 bytes。
2、在以前测试的时候,发现send函数发送的结果有可能失败的,从返回的参数结果可以知道,这样就还需要重发。
3、发送的数据包顺序不能混乱。
1、要发送/接收的数据包可能比较大,有几十KB左右,但是为了传输安全,现在需要进行分包的传输,每一个包最大为1024 bytes。
2、在以前测试的时候,发现send函数发送的结果有可能失败的,从返回的参数结果可以知道,这样就还需要重发。
3、发送的数据包顺序不能混乱。
2、由于是非阻塞,如程序没有错的话,send最有可能的错误是10035(WSAEWOULDBLOCK),这样的话其实这次根本就没发
3、、、、、、、、、
ok:
char buf[几十KB];
BOOL fgwrite=false;
static int ret=0,idx=0,len=几十KB;while(fgwrite)
{
ret=send(&buf[idx],1024...);
if(ret==10035)
{
fgwrite=false;
break;
}
if(ret!=1024)
return;
idx+=ret;
len-=ret;
if(len==0) over;
}
------------------
case FD_WRITE:
fgwrite=true;
break;随手写的,不清楚的话再说
ret=send(&buf[idx],1024...);
if(ret==10035)
这里有问题啊,假设是发送失败的话,返回的ret==0,只有getlasterror()之后才返回10035的错误
if(ret<0)
{
ret=GetLastError();
if(ret==10035)
{
fgwrite=false;
break;
}
}
说一点共参考:
用多个buf,标记当前要发的buf:如果是因为10035出错就接着发,不然的话就发下一个buf,
或:
如果主要是10035错误,你可以用setsockopt将发送缓存改为64k,或大于你的保长,这样还用上面的代码,不会出现因为10035而只发半个包的情况,如果就数据包是另外线程产生,就要注意县城同步,保证包之间的顺序WSAAsyncSelect IO可能时间上要慢些,而且有些情况较复杂,如果可能的话,用阻塞方式相对简单些。继续交流....
我这边的数据发送的确复杂,你想想有没有这样的情况发生,服务器正常发送了一个数据包,返回不出错,但是客户端接收的时候发生了错误,也许是10035什么的,这样就会造成服务器以为数据正常发送完毕,但其实客户端没有正常接收的情况呢???
setsockopt(s ,SOL_SOCKET,SO_RCVBUF,(char *)&buflen,optlen);
SO_RCVBUF:系统的接收缓存
SO_SNDBUF:系统的发送缓存对于消息异步,接受方WSAEWOULDBLOCK(10035)是很正常的事,原因是:如果你在统接收缓存中没有数据时调用recv(),就会产生该错误,所以,在消息异步中,一般都是在响应FD_READ消息中调用recv(),同理,发送端如果发送缓存已满后还调用send(),便产生该错误,只不过没人知道事么时候发送缓存已满,所已,默认是未满,即可以发送,真得要是满了,系统会告诉你的(send()返回错误号10035),此后,如果系统在此允许发送的话,他便会发FD_WRITE来告诉你,这就是我在上面设fgwrite的目的。
至于发生其他错误,没办法,不管你用那种传输方法,都有可能发生这种意外错误,就看你怎么处理了。
如果是udp的话,有可能出现服务器以为数据正常发送完毕,但其实客户端没有正常接收的情况,对于tcp,是连接的流协议,会保证你安顺序接受的。
你能告诉我,send函数发送失败后getlasterror()有哪些值吗?
不客气,分无所谓的
是不是说TCP发送一个30KB信息之后,假设它内部是分开发送的,就算一部分没有发送完毕,也会出现一个10035错误,叫你重新发送一次得的,对吗?
unsigned long SockMode=1;
ioctlsocket(ASClientSocketInfo.ConnectSocket,FIONBIO,&SockMode);
,但是根本没用,还是阻塞,不知道怎么样才可以设置一个超时的时间啊$%$#%#$#@$