历史原因,我们在使用VC6给客户制作动态库其中有一段这样的代码:
服务器端(HP-UNIX)接收到客户端(windows的动态库)发送的请求,请求大约1000字节,其中头16字节,头16字节中有一个字段是用来标识版本号的,HP-UNIX服务器端先接收16字节,校验,版本号错误的话,直接把错误码赋给一个结构后write回客户端, 然后close这个fd。(结构是我们定义的通讯结构)现在的问题是: 服务器端的close和客户的recv不确定是谁先执行,于是出现下面的状况:
1:服务器先close,recv返回10054错误(连接已经reset)
2:客户先recv, 正常接收到我们业务的错误码这是动态库的代码,
如果我把代码原封不动的复制出来,编译成一个控制台程序,无论1,2哪种情况,客户都会正常接收到业务错误码但是, 根据TCP/IP的原理, 即使对方close, 但是它在close之前write了一些东西,我之后recv,也应该能接收到它write的东西啊, 为何动态库就会返回10054呢?还有一个现象:服务器不是先接收16字节吗, 如果改为服务器检测到错误的版本号之后,继续接收完剩余的字节,无论1,2,客户端都会正常接收到业务错误码,而不是recv返回10054。

解决方案 »

  1.   

    你调用了shutdown函数了吗?
      

  2.   

    closesocket前shutdown,服务器最好linger
      

  3.   

    第一点:
    发送完数据后,用Sleep延时一会。
    第二点:
    可能是你服务端代码有问题。见意贴代码。
      

  4.   

    你应该使用的是异步Socket吧,你可以通过查询消息,确认数据正常发送了再close
      

  5.   


    sleep的方法不可取吧,测试还可以,实际应用好像没人敢这么做,服务器端视HP-UX,Richard Steven先生的《UNIX网络编程》上不是说:(socket的默认属性)close之后,内核会确保所有的数据发送。而我的理解,TCP数据的发送接收时内核实现的,不应该因为我没有调用recv就会接受不到数据啊!
      

  6.   


    服务器sleep,recv确实成功的,我这个测试结果忘贴出来了
      

  7.   


    这位仁兄的“异步socket”指的是windows上的吧,
    我的代码中客户端不close,服务器close,