TCP相关API介绍与服务端编写
TCP的概念:
TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层协议。
TCP 的关键特性和介绍:
- 面向连接:
TCP是一种面向连接的协议,在数据传输之前,发送方和接收方需要建立一个连接。连接建立后,数据的传输是双向的,并且在传输完成后会释放连接。
- 可靠性:
TCP 提供可靠的数据传输。它使用序号、确认和重传机制来确保数据能够正确地到达目的地,即使在网络中发生了丢包或乱序的情况下也能够进行恢复。
- 流式传输:
TCP是基于字节流的协议,数据被划分为一个个的字节流进行传输。发送方发送的数据以字节流的形式传输到接收方,接收方将这些字节流重新组装成完整的数据。
- 拥塞控制:
TCP 通过拥塞控制算法来避免网络拥塞。它能够根据网络的拥塞程度调整数据的传输速率,以保持网络的稳定性和高效性。
- 全双工通信:
TCP 支持全双工通信,即发送方和接收方可以同时进行数据的发送和接收。
- 流量控制:
TCP 使用流量控制机制来确保发送方不会发送过多的数据给接收方,从而避免接收方的缓冲区溢出。
- TcpClient
是.NET Framework中的一个类,提供了与TCP/IP主机连接和进行数据交换的简单方法。它属于System.Net.Sockets命名空间,通常在C#中用于网络应用程序。
- TcpListene
TcpListener 是一个.NET Framework中的类,用于在TCP/IP网络上监听传入的连接请求。
- TcpListener.Create()
TcpListener.Create()创建一个监听器,侦听指定的端口。
用法:
TcpListener tcpListener;
cpListener = TcpListener.Create(端口号);
- tcpListener.AcceptTcpCientAsync()
tcpListener.AcceptTcpCientAsync()接受客户端的连接请求。
用法:
> public Client client; TcpClient tcpClient = await
> tcpListener.AcceptTcpClientAsync();
- client.GetStream().ReasAsync()
client.GetStream().ReasAsync()接受服务端传过来的数据,数据是从客户端的网络流 (NetworkStream)
中读取的。这是一个异步操作,它会等待客户端发送数据,并从网络流中读取字节。一旦有数据可用,就会返回一个表示已读取数据的字节数
用法:
byte[] buff = new byte[4096];
//用于存储从网络接收到的消息。这个数组被称为缓冲区(buffer)
int length = await client.GetStream().ReadAsync(buff, 0, buff.Length);
- client.GetStream().WriteAsync()
client.GetStream().WriteAsync()发送数据给客户端,用于将数据写入到客户端的网络流
(NetworkStream) 中。这同样是一个异步操作,它将指定的数据写入到网络流中。
用法:
await client.GetStream().WriteAsync(data, 0, data.Length);
- client.Close()
关闭客户端的连接
用法:
client.Close();
服务端
###主函数(调用启动服务器函数以及监听客户端是否传来数据)
namespace Server
{
internal class Program
{
static void Main(string[] args)
{
TCPServer tCPServer = new TCPServer();//实例一个服务端的对象
//启动服务端
tCPServer.Start();
while (true)//一直循环监听
{
//标准输入流(默认为键盘)中读取下一行字符,并将该行作为字符串返回
var str = Console.ReadLine();
//var jsonStr = JsonHelper.GetTestToString();
// tCPServer.tempClient.Send(Encoding.UTF8.GetBytes(str));
//tCPServer.client.Send(Encoding.UTF8.GetBytes(str));
//tCPServer.client.Send(Encoding.UTF8.GetBytes(jsonStr));
}
}
}
}
###服务器下的Client类(接收客户端发来的消息以及发送响应)
namespace Server.Net
{
internal class Client
{
TcpClient client;//创建TCP连接的客户端的类
public Client(TcpClient tcpClient) {
client = tcpClient;
Receive();//接受客户端发来的消息函数
}
//接受客户端的消息
public async void Receive()
{
//处于连接状态
while (client.Connected)
{
try
{
byte[] buffer = new byte[4096];
//读取客户端发送来的数据
int length = await client.GetStream().ReadAsync(buffer, 0, buffer.Length);
//它使用一个循环和 ReadAsync 方法从客户端流中读取数据,并将其存储在内存流中。最后,将内存流中的数据转换为字符串进行处理。
if (length > 0)//数据有长度的时候
{
Console.WriteLine($"接受到数据长度:{length}");
Console.WriteLine($"接受到数据内容:{Encoding.UTF8.GetString(buffer, 0, length)}");//将buffer字节数组转换成字符串打印出
}
else
{
//客户端关闭了
client.Close();
}
}
catch (Exception e)
{
Console.WriteLine($"Receive Error:{e.Message}");
//出现错误将客户端给关闭掉
client.Close();
}
}
}
//发送响应消息
public async void Send(byte[] data)
{
try
{
await client.GetStream().WriteAsync(data, 0, data.Length);//将数据写入网络数据流,也就是发送响应消息给客户端
Console.WriteLine("发送成功");
}
catch (Exception e)
{
client.Close();
Console.WriteLine($"send error:{e.Message}");
}
}
}
###服务器下的TCPServer类(启动服务器的函数以及与接受客户端发来的连接请求)
namespace Server.Net
{
internal class TCPServer
{
TcpListener tcpListener;
//启动服务端
public void Start()
{
try
{
//创建监听器,这里不指定端口默认主机的IP端口
tcpListener = TcpListener.Create(7788);
//启动监听器,参数是最大连接队列长度
tcpListener.Start(500);
Console.WriteLine("TCP Server Start");
//启动服务器后调用客户端连接
Accpet();//接受客户端传来的消息
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public Client tempClient;
public Client client;
//async改成异步,监听客户端的连接
public async void Accpet()
{
try
{
//接受客户端连接
TcpClient tcpClient = await tcpListener.AcceptTcpClientAsync();
//将客户端的IP地址打印
Console.WriteLine("客户端已连接:" + tcpClient.Client.RemoteEndPoint);
//构建一个Client
client = new Client(tcpClient);
tempClient = client;//将连接过来的客户端赋值给tempClient
//继续接受来自客户端的连接
Accpet();
}
catch (Exception e)
{
Console.WriteLine($"Accpet:{e.Message}");
tcpListener.Stop();//停止监听客户段的连接
}
}
}
}