Socket笔记【转】

1、  为了增加效率,可以考虑采用无异常的函数 
在.net2.0中Socket.Send,Socket.Receive 有了无异常的函数 
Socket.Send(Byte[], Int32, Int32, SocketFlags, SocketError) 
Socket.Receive(Byte[], Int32, Int32, SocketFlags, SocketError) 
减少不必要的异常,就等于增加效率。

2、Socket.Connected 不是当前的Socket状态 
MSDN原文:获取一个值,该值指示 Socket 是在上次 Send 还是 Receive 操作时连接到远程主机。 
应当如何解决呢?

同样   MSDN   也告诉了我们:  
Connected 
属性的值反映最近操作时的连接状态。如果您需要确定连接的当前状态,请进行非阻止、零字节的   Send  调用。   如果该调用成功返回或引发   WAEWOULDBLOCK  错误代码   (10035)   ,则该套接字仍然处于连接状态;否则,该套接字不再处于连接状态。  
3
  、要用Socket.Poll判断是否可以接收,不要用Socket.Available  
虽然   Socket.Available   可以偷窥到当前   Recv   缓冲区字节数,而且   Available     Poll   速度的两倍,但是   MSDN   说到   :如果远程主机使用 Shutdown  方法关闭了   Socket  连接,并且所有可用数据均已收到,则   Receive  方法将立即完成并返回零字节。  
所以当网络断开的时候单纯使用   Socket.Available   判断是否   recv   到数据会存在不知道客户端已经断开   Bug 
补充:   不推荐使用   Socket.Poll     Socket   的列表遍历,应当使用   Socket.Select   (或者其他模型),   Socket.Poll   是对   Socket.Select   的封装,执行   Socket.Poll   耗时是非阻塞   Socket.Recv   的三倍。  
4
  、非阻塞模式不能采用Receive的返回值表示是否断开  
  3   条说道:如果远程主机使用   Shutdown  方法关闭了   Socket  连接,并且所有可用数据均已收到,则   Receive  方法将立即完成并返回零字节。但这并不能阻塞模式说明   Socket   已经断开,   这一条和   C     recv   函数不同,需要特别注意   。需要判断   out   出来的   SocketError   ,当不为   SocketError.Success     SocketError.Interrupted     SocketError.WouldBlock   时就可以认为网络已经断开。  
5
  Send可能出现缓冲区满的情况  
判断   out   出来的   SocketError   ,如果等于   SocketError.WouldBlock   ,则是   Send   缓冲区已满,应断开该   Socket   ,否则影响整体速度,而不应当   again,  反过来说允许的错误码只有   SocketError.Interrupted   ,此时可以重来一次。  
6
  、主动断开Socket 
MSDN   说道   :   如果当前使用的是面向连接的   Socket   ,则必须先调用   Shutdown  方法,然后才能关闭   Socket   。这可以确保在已连接的套接字关闭之前,已发送和接收该套接字上的所有数据。  
所以,网络库的   Close   函数可以封装为先调用   Shutdown(SocketShutdown.Both)   ,在调用   Close()    
7
  Socket已经关闭(Close)但不能在另一端断开  
一端   Scoket   已经关闭了,但另一端短时间内仍可以发送数据!这个问题还没有找到解决办法的,但原因已知,   在《   Windows   网络编程技术》一书   (P139-P140)   中说道   :   被动关闭的情况下,应用程序会从对方那里接收一个   FIN   包,并用一个   ACK   包做出响应。此时,应用程序的套接字会变成   ClOSE_WAIT   状态。由于对方已关闭自己的套接字,所以不能再发送数据了。   但应用程序却不同,它能一直发送数据,直到对方的套接字已关闭为止。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值