发送一个数据包,怎样判断数据发送完整完全

Xiaoyi2122 2016-02-03 02:11:44
var ary=encoding.GetBytes(builder.ToString());
var array=new byte[ary.Length+4];
var lenForByteArray = BitConverter.GetBytes(ary.Length);
Array.Copy(lenForByteArray, array, 4);
Buffer.BlockCopy(ary, 0, array, 4, ary.Length);

socket.BeginSend(array, 0, array.Length, SocketFlags.None, new AsyncCallback(SendCallBack), socket);

private void SendCallBack(IAsyncResult ar)
{
Socket senSocket = (Socket)ar.AsyncState;
var len= senSocket.EndSend(ar);
if(len<??)
//??怎么判断发送数据的长度就是我本该发送的长度,如果一次没有发送完全,接下来继续发送怎样写呢?
}

请教各位
...全文
737 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
本拉灯 2016-02-04
  • 打赏
  • 举报
回复
引用 13 楼 johnliuyuan 的回复:
[quote=引用 11 楼 sp1234 的回复:] 对于 tcp,它是可靠的,不可能只发送一部分。因此你判断 len 是没有必要的。
TCP还有粘包和半包的情况,所以判断一下是正确的。 9楼的思路正确[/quote] 粘包和半包 跟发送端没任何关系,只有接收端才去判断。
puler 2016-02-04
  • 打赏
  • 举报
回复
如果对数据要求精确度非常严格,个人感觉还是类似编码校验这类的方法,可以自己写,也可以参考开源的项目
crystal_lz 2016-02-04
  • 打赏
  • 举报
回复
Send 都会把你 的byte[] 一次性发送出去 根本不用管 你需要管的就是 对你的数据 定义一个协议
john_QQ:2335298917 2016-02-03
  • 打赏
  • 举报
回复
引用 11 楼 sp1234 的回复:
对于 tcp,它是可靠的,不可能只发送一部分。因此你判断 len 是没有必要的。
TCP还有粘包和半包的情况,所以判断一下是正确的。 9楼的思路正确
  • 打赏
  • 举报
回复
换个角度看,假设我们“闲着没事儿”非要纠结一下这个代码怎么写,那么使用“匿名委托”是最方便的写法。例如可以写
   socket.BeginSend(array, 0, array.Length, SocketFlags.None, ar=>{
            Socket senSocket = socket;
            var len= senSocket.EndSend(ar);
            if(len!= array.Length)
                      .........................
}, socket);
 
这样的匿名委托,在委托方法中可以直接访问 array 和 socket,省得你再去动脑筋去按照你那种方式设计相关代码了。
  • 打赏
  • 举报
回复
对于 tcp,它是可靠的,不可能只发送一部分。因此你判断 len 是没有必要的。
Xiaoyi2122 2016-02-03
  • 打赏
  • 举报
回复
引用 9 楼 Forty2 的回复:
private void SendCallBack(IAsyncResult ar)
{
    MyState state = (MyState)ar.AsyncState;
    state.offset += state.socket.EndSend(ar); // 这里更正上贴的错误
    if(state.offset < state.array.Length)
    {
        state.socket.BeginSend(
            state.array, state.offset, state.array.Length - state.offset, 
            SocketFlags.None, SendCallBack, state);
    }
}
state.offset是索引,永远小于array.Length吧,不就会无限循环?
Forty2 2016-02-03
  • 打赏
  • 举报
回复
private void SendCallBack(IAsyncResult ar)
{
    MyState state = (MyState)ar.AsyncState;
    state.offset += state.socket.EndSend(ar); // 这里更正上贴的错误
    if(state.offset < state.array.Length)
    {
        state.socket.BeginSend(
            state.array, state.offset, state.array.Length - state.offset, 
            SocketFlags.None, SendCallBack, state);
    }
}
Forty2 2016-02-03
  • 打赏
  • 举报
回复
引用 楼主 zhangxiao0122 的回复:
... Socket senSocket = (Socket)ar.AsyncState; ...
AsyncState可以是Socket,也可以是你任意定义的对象。也就是说你可以把array等信息也放到AsyncState里面: class MyState { public Socket socket; public byte[] array; public int offset; } 这样一来,你就可以利用MyState接着发送:
private void SendCallBack(IAsyncResult ar)
        {
            MyState state = (MyState)ar.AsyncState;
            var len= state.socket.EndSend(ar);
            if(len + state.offset < state.array.Length)
            {
                socket.BeginSend(state.array, state.offset, state.array.Length - state.offset, ...);
            }
        }
xdashewan 2016-02-03
  • 打赏
  • 举报
回复
引用 5 楼 zhangxiao0122 的回复:
我定义的数据包是包头存包体的长度,接收时根据包头的数据来接收足够的包体数据, 发送的时候也是按照这种形式发送,但可能一次发送不完,所以需要判断一下再继续发送 就是这部分如何实现
这种类型,要么事先就分配好,要么就是每次发完做比较
Xiaoyi2122 2016-02-03
  • 打赏
  • 举报
回复
我定义的数据包是包头存包体的长度,接收时根据包头的数据来接收足够的包体数据, 发送的时候也是按照这种形式发送,但可能一次发送不完,所以需要判断一下再继续发送 就是这部分如何实现
wanghui0380 2016-02-03
  • 打赏
  • 举报
回复
你管他做什么,直接一个队列,先进先出。
  • 打赏
  • 举报
回复
自定义发送结构,将内容长度作为参数在结构头发送,结尾加个结束标示。接收方接收到结束标识后判断共接收了多少个字节长度,与结构头的内容长度对比。
Xiaoyi2122 2016-02-03
  • 打赏
  • 举报
回复
[quote=引用 1 楼 xdashewan 的回复:] 你发送内容要么全局能访问,要么放BeginSend最后一参数里传过去,不然无法获取[/qu 内容全局的作用呢,不是只要长度全局就好吗,
wanghui0380 2016-02-03
  • 打赏
  • 举报
回复
让对方确认,自己不确认。 每个封包加校验码,让接收方确认。
xdashewan 2016-02-03
  • 打赏
  • 举报
回复
你发送内容要么全局能访问,要么放BeginSend最后一参数里传过去,不然无法获取

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧