• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C#中Socket进行数据接收的一点心得

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
在利用Socket 进行Tcp/Ip 编程的时候,免不了要进行数据的发送和接收,而数据的接收,用得最多的就是 Socket 的同步函数 Receive (或它的重载):
public int Receive (
    byte[] buffer,
    int offset,
    int size,
    SocketFlags socketFlags
)
或者是异步函数 BeginReceive( 或它的重载): public IAsyncResult BeginReceive (
    byte[] buffer,
    int offset,
    int size,
    SocketFlags socketFlags,
    AsyncCallback callback,
    Object state
)
这里,我想说的是异步函数 BeginReceive()。

使用了异步函数BeginReceive(),伴随而来的就是要定义一个 AsyncCallback 类型的函数(如下面取名为ReceiveEnd的函数),在这个函数里面,我们最少要做的事情时调用 Socket 的 EndReceive() 函数。 protected void ReceiveEnd(IAsyncResult ar){
    Socket client = (Socket)ar.AsyncState;
    int recvLen = client.EndReceive(ar);

    if ( recvLen > 0){        /**//* 接收到了数据 */
        client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveEnd), client);  /**//* 继续接收数据*/
    }
    else{
        client.Close();      
    }
}
在Msdn 2005 的 ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.NETDEVFX.v20.chs/cpref10/html/M_System_Net_Sockets_Socket_BeginReceive_3_2b547d4d.htm
基本上就是上面这个意思,但是现在问题来了:
如果我定义的 buffer 的长度为 10,但我发送的数据长度为12或者8,那么,函数就不会走到 else 的部分,而是阻塞在函数中的 BeginReceive()调用。

开始,我的想法是在发送的数据尾部增加一个特殊的字符(串),然后,在接收的时候判断有没有接收到这个字符(串)(我查阅了网上一些资料,还真有一些是这么做的!),但是,这种做法始终有一个毛病:那就是发送端发送的正文里面不能含有这个字符(串),否则,正文中在这个字符(串)后面的正文就会被丢掉。
所以,我想还是只能通过 Socket 自己的内部机制来实行,也就是想办法使程序走到 else 的部分。
经过测试:
在客户端发送完数据后,使用 Socket.Shutdown(SocketShutdown.Send ),或者Socket.Close()可以使程序走到 else 部分。
但是,这也带来了一个问题:
如果我定义的buffer 的长度为10,我发送的数据的长度也刚好为10,那么,函数在客户端不用Shutdown或Close的情况下,就已经走到了else 部分,然后 服务端的Socket 被 Close,等到客户端使用 Shutdown()或Close() 的时候,服务端的连接 Socket 已经是不可用了,而这个时候调用 EndReceive 操作,会引发异常。
所以,我认为在调用 EndReceive 前,先要判断 Socket 是否可用。(这个结论尚未测试)

同时,我测试将Socket.Shutdown(SocketShutdown.Send ),改为Socket.Shutdown(SocketShutdown.Receive ),并不能引发函数走到 else 部分,所以,我认为Socket 的Shutdown(SocketShutdown.Send )和Close()会引发客户端与服务端的一次数据传输。 

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
[C#]LINQ中如何按实体的某个属性去重DistinctBy发布时间:2022-07-10
下一篇:
C#使用Win32函数的一些类型转换发布时间:2022-07-10
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap