建议楼主去网上查查TCP传输的通常方式
我给你提供一个最简单也最好理解的解决方案吧。
首先客户端是知道我当次会话传输数据的长度吧,其实这就是个相互规定的协议而已,你们做传输客户端和服务端应该先定好协议
例如:
socket.Send("111"); // 第一次(假设是第一个包)
socket.Send("222"); //第二次(假设是第二个包)
socket.Send("333数据乱发长度不等"); //第三次(假设是第三个包)
一般应该是这样做,发送每个包的时候在包头都要带上这个包的长度,其实就是你send(byte[])的时候,在byte[]前几个字节放入当前包的长度,
例如:当前发送的数据为"111"那么你先要取到“111” 的长度,然后放到待发送的byte[]的前2个字节里(不一定是前两个,这个要客户端和服务端相一致,到时候服务端只取前2个字节即可知道包的长度了),然后再把“111”序列化成byte[] 放到待发送的byte[]里去。然后发送即可,这样服务端得到数据之后首先要解析这个包的长度,然后再根据这个长度去取相同长度的数据. 我说到这够明白了么?
在给你解释一下吧
假设
socket.Send("111");
socket.Send("222");
socket.Send("asdfsafd乱七八糟不定长");
这时候出现服务端一次性接收的情况
按照我之前说的结构来做的话
那你服务端接受到的数据就是这样的
111的长度+111的byte[]数组+222的长度+222的byte[]数组+asdfsafd乱七八糟不定长的长度+asdfsafd乱七八糟不定长的byte[]数组
当然 111的长度 222的长度 这些都是在客户端 .Length 求出来的,然后序列化即可
在服务端只需取到第一个包的长度,按照长度取相应长度的数据,这个样能取到111,以此类推,这样每个包都可以分开了,只要你逻辑写的对,这样分包绝对没有问题
Send:
BufferedStream bs = new BufferedStream(tcpClient.GetStream());
bs.Write("111");
bs.Write("222");
bs.Write("333");
bs.Write(DateTime.Now);
Receive:
BufferedStream bs = new BufferedStream(tcpClient.GetStream());
string str1=bs.ReadString();
string str2=bs.ReadString();
string str3=bs.ReadString();
DateTime dt = bs.ReadDateTime();
我给你提供一个最简单也最好理解的解决方案吧。
首先客户端是知道我当次会话传输数据的长度吧,其实这就是个相互规定的协议而已,你们做传输客户端和服务端应该先定好协议
例如:
socket.Send("111"); // 第一次(假设是第一个包)
socket.Send("222"); //第二次(假设是第二个包)
socket.Send("333数据乱发长度不等"); //第三次(假设是第三个包)
一般应该是这样做,发送每个包的时候在包头都要带上这个包的长度,其实就是你send(byte[])的时候,在byte[]前几个字节放入当前包的长度,
例如:当前发送的数据为"111"那么你先要取到“111” 的长度,然后放到待发送的byte[]的前2个字节里(不一定是前两个,这个要客户端和服务端相一致,到时候服务端只取前2个字节即可知道包的长度了),然后再把“111”序列化成byte[] 放到待发送的byte[]里去。然后发送即可,这样服务端得到数据之后首先要解析这个包的长度,然后再根据这个长度去取相同长度的数据. 我说到这够明白了么?
在给你解释一下吧
假设
socket.Send("111");
socket.Send("222");
socket.Send("asdfsafd乱七八糟不定长");
这时候出现服务端一次性接收的情况
按照我之前说的结构来做的话
那你服务端接受到的数据就是这样的
111的长度+111的byte[]数组+222的长度+222的byte[]数组+asdfsafd乱七八糟不定长的长度+asdfsafd乱七八糟不定长的byte[]数组
当然 111的长度 222的长度 这些都是在客户端 .Length 求出来的,然后序列化即可
在服务端只需取到第一个包的长度,按照长度取相应长度的数据,这个样能取到111,以此类推,这样每个包都可以分开了,只要你逻辑写的对,这样分包绝对没有问题
------其他回答(40分)---------
-
C# code
-
namespace sys.io { using System; using System.Collections.Generic; using System.Text; #region BufferedStream /// <summary> /// 缓存流 /// </summary> public class BufferedStream : System.IO.Stream { System.IO.Stream stream; /// <summary> /// 构建一个内存缓冲流 /// </summary> public BufferedStream() : base() { stream = new System.IO.MemoryStream(); } /// <summary> /// 从基础流构建流 /// </summary> /// <param name="stream">源流</param> public BufferedStream(System.IO.Stream stream) { this.stream = stream; } /// <summary> /// 从字节数组构建缓冲流 /// </summary> /// <param name="bytes">字节数组</param> public BufferedStream(byte[] bytes) { stream = new System.IO.MemoryStream(bytes); } /// <summary> /// 将整个流内容写入字节数组,而与 System.IO.MemoryStream.Position 属性无关。 /// </summary> /// <exception cref="System.InvalidOperationException">如果源流不是一个内存流,将引发此异常</exception> /// <returns></returns> public byte[] ToArray() { System.IO.MemoryStream ms = stream as System.IO.MemoryStream; if (ms == null) throw new InvalidOperationException(); return ms.ToArray(); } public void Write(long value) { this.Write(BitConverter.GetBytes(value)); } public void Write(ulong value) { this.Write(BitConverter.GetBytes(value)); } public void Write(ushort value) { this.Write(BitConverter.GetBytes(value)); } public void Write(int value) { this.Write(BitConverter.GetBytes(value)); } public void Write(DateTime value) { this.Write(BitConverter.GetBytes(value.Ticks)); } public void Write(uint value) { this.Write(BitConverter.GetBytes(value)); } public void Write(byte[] bytes) { this.Write(bytes, 0, bytes.Length); } public void Write(string value) { byte[] buff = Encoding.UTF8.GetBytes(value); this.Write(BitConverter.GetBytes((ushort)buff.Length)); this.Write(buff); } public void WriteObject(object obj) { byte[] bytes = null; using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) { using (System.IO.Compression.GZipStream gz = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Compress)) { System.Runtime.Serialization.IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); formatter.Serialize(gz, obj); bytes = ms.GetBuffer(); } } this.Write(bytes.Length); this.Write(bytes); } public void WriteUserId(string userId) { byte[] buff = Encoding.UTF8.GetBytes(userId); this.WriteByte((byte)buff.Length); this.Write(buff); } public object ReadObject() { int len = this.ReadInt(); byte[] bytes = this.Read(len); using (System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes)) { using (System.IO.Compression.GZipStream gz = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Decompress)) { System.Runtime.Serialization.IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); return formatter.Deserialize(gz); } } } public uint ReadUInt() { return BitConverter.ToUInt32(Read(4), 0); } public int ReadInt() { return BitConverter.ToInt32(Read(4), 0); } public ushort ReadUShort() { byte[] bytes = Read(2); return BitConverter.ToUInt16(bytes, 0); } public DateTime ReadDateTime() { byte[] bytes = Read(8); return new DateTime(BitConverter.ToInt64(bytes, 0)); } public string ReadString() { ushort len = ReadUShort(); byte[] buff = Read(len); return Encoding.UTF8.GetString(buff); } public string ReadUserId() { byte len = (byte)ReadByte(); byte[] buff = Read(len); return Encoding.UTF8.GetString(buff); } public byte[] Read(int len) { byte[] buff = new byte[len]; this.Read(buff, 0, len); return buff; } public override bool CanRead { get { return stream.CanRead; } } public override bool CanSeek { get { return stream.CanSeek; } } public override bool CanWrite { get { return stream.CanWrite; } } public override void Flush() { stream.Flush(); } public override long Length { get { return stream.Length; } } public override long Position { get { return stream.Position; } set { stream.Position = Position; } } public override int Read(byte[] buffer, int offset, int count) { return stream.Read(buffer, offset, count); } public override long Seek(long offset, System.IO.SeekOrigin origin) { return stream.Seek(offset, origin); } public override void SetLength(long value) { stream.SetLength(value); } public override void Write(byte[] buffer, int offset, int count) { stream.Write(buffer, offset, count); } public override void Close() { stream.Close(); base.Close(); } } #endregion }
Send:
BufferedStream bs = new BufferedStream(tcpClient.GetStream());
bs.Write("111");
bs.Write("222");
bs.Write("333");
bs.Write(DateTime.Now);
Receive:
BufferedStream bs = new BufferedStream(tcpClient.GetStream());
string str1=bs.ReadString();
string str2=bs.ReadString();
string str3=bs.ReadString();
DateTime dt = bs.ReadDateTime();
本文详细介绍了TCP传输中如何通过协议规定实现数据包的正确组装与分发,包括客户端和服务端之间的交互规则,以及如何在发送数据时携带包长度信息以确保服务端能够准确解析并处理接收到的数据。
1482

被折叠的 条评论
为什么被折叠?



