C#网络编程之TCP(三)

一、数据的发送规则

  在上一篇章说道,tcp的数据传输在网络信道中是以字节的方式传输的,接受方并不知道数据的具体长度,每次按照固定的长度进行读取,那么在读取数据的时候会出现和我们想象的不一样的结果。

  服务端

const string ip = "127.0.0.1";
const int port = 10002;

// 建立服务器
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
EndPoint point = new IPEndPoint(IPAddress.Parse(ip), port);
socket.Bind(point);
socket.Listen();
Console.WriteLine("服务器启动,等待连接...");

// 监听客户端发起连接
Socket conn = socket.Accept();
Console.WriteLine("有客户端连接...");

// 发送数据
string outputMsg1 = "Hello World!";
string outputMsg2 = "你好世界";
conn.Send(Encoding.UTF8.GetBytes(outputMsg1));
conn.Send(Encoding.UTF8.GetBytes(outputMsg2));
Console.WriteLine(">>: " + outputMsg1);
Console.WriteLine(">>: " + outputMsg2);


// 关闭连接
conn.Close();

  客户端

const string ip = "127.0.0.1";
const int port = 10002;

// 连接至服务器
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
EndPoint point = new IPEndPoint(IPAddress.Parse(ip), port);
socket.Connect(point);
Console.WriteLine("客户端启动,连接到服务器...");

// 接收数据
byte[] bytes = new byte[1024];
int len = socket.Receive(bytes);
string inputMsg1 = Encoding.UTF8.GetString(bytes, 0, len);
Console.WriteLine("<<: " + inputMsg1);

// 接收数据
byte[] bytes2 = new byte[1024];
int len2 = socket.Receive(bytes2);
string inputMsg2 = Encoding.UTF8.GetString(bytes2, 0, len2);
Console.WriteLine("<<: " + inputMsg2);

// 关闭连接
socket.Close();

 

   客户端连上服务端后,服务端连续发送了2条信息:"Hello World!","你好世界";客户端也连续接收了2次数据。从结果上看,客户端可能第一次就接收到了全部的数据,或是接收到的数据不完整。

 二、数据的完整性

  该怎么解决上述的问题呢?这就需要我们自己定制新的规则。

  1.发送方:byte[4] + byte[N]

  2.接收方:先接收4字节得知长度信息N,在接收N字节

  服务端

const string ip = "127.0.0.1";
const int port = 10002;

// 建立服务器
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
EndPoint point = new IPEndPoint(IPAddress.Parse(ip), port);
socket.Bind(point);
socket.Listen();
Console.WriteLine("服务器启动,等待连接...");

// 监听客户端发起连接
Socket conn = socket.Accept();
Console.WriteLine("有客户端连接...");

// 发送数据
string outputMsg1 = "Hello World!";
string outputMsg2 = "你好世界";


byte[] buf = new byte[4];
// 先发送内容的长度
ConvertIntToByteArray(Encoding.UTF8.GetBytes(outputMsg1).Length, ref buf);
conn.Send(buf);
// 再发送内容
conn.Send(Encoding.UTF8.GetBytes(outputMsg1));

// 先发送内容的长度
ConvertIntToByteArray(Encoding.UTF8.GetBytes(outputMsg2).Length, ref buf);
conn.Send(buf);
// 再发送内容
conn.Send(Encoding.UTF8.GetBytes(outputMsg2));

Console.WriteLine(">>: " + outputMsg1);
Console.WriteLine(">>: " + outputMsg2);


// 关闭连接
conn.Close();

static bool ConvertIntToByteArray(Int32 m, ref byte[] arry)
{
    if (arry == null) return false;
    if (arry.Length < 4) return false;

    arry[0] = (byte)(m & 0xFF);
    arry[1] = (byte)((m & 0xFF00) >> 8);
    arry[2] = (byte)((m & 0xFF0000) >> 16);
    arry[3] = (byte)((m >> 24) & 0xFF);

    return true;
}

  客户端

const string ip = "127.0.0.1";
const int port = 10002;

// 连接至服务器
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
EndPoint point = new IPEndPoint(IPAddress.Parse(ip), port);
socket.Connect(point);
Console.WriteLine("客户端启动,连接到服务器...");

// 接收数据
byte[] bytes = new byte[4];
// 先获取内容长度
socket.Receive(bytes);
int inputLength1 = BitConverter.ToInt32(bytes, 0);
byte[] msgBytes1 = new byte[inputLength1];
// 再获取内容
socket.Receive(msgBytes1);
string inputMsg1 = Encoding.UTF8.GetString(msgBytes1, 0, inputLength1);
Console.WriteLine("<<: " + inputMsg1);


// 接收数据
// 先获取内容长度
socket.Receive(bytes);
int inputLength2 = BitConverter.ToInt32(bytes, 0);
byte[] msgBytes2 = new byte[inputLength2];
// 再获取内容
socket.Receive(msgBytes2);
string inputMsg2 = Encoding.UTF8.GetString(msgBytes2, 0, inputLength2);
Console.WriteLine("<<: " + inputMsg2);

// 关闭连接
socket.Close();

 

 

posted @ 2022-08-10 17:55  Zeng。  阅读(998)  评论(0编辑  收藏  举报