【C#】Socket网络编程(TCP)
本篇主要围绕Socket网络编程基于TCP协议
TCP协议
TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
讲到TCP就顺带把三次握手和四次挥手也一起复习了吧…
三次握手
TCP是因特网中的传输层协议,使用三次握手协议建立连接。当主动方发出SYN连接请求后,等待对方回答
SYN+ACK,并最终对对方的 SYN 执行 ACK 确认。这种建立连接的方法可以防止产生错误的连接,TCP使用的流量控制协议是可变大小的滑动窗口协议。
TCP三次握手的过程如下:
(1) 客户端发送SYN(SEQ=x)报文给服务器端,进入SYN_SEND状态。
(2) 服务器端收到SYN报文,回应一个SYN (SEQ=y)ACK(ACK=x+1)报文,进入SYN_RECV状态。
(3) 客户端收到服务器端的SYN报文,回应一个ACK(ACK=y+1)报文,进入Established状态。
三次握手完成,TCP客户端和服务器端成功地建立连接,可以开始传输数据了。
图来自百度百科…
四次挥手
建立一个连接需要三次握手,而终止一个连接要经过四次握手,这是由TCP的半关闭(half-close)造成的。
(1) 某个应用进程首先调用close,称该端执行“主动关闭”(active close)。该端的TCP于是发送一个FIN分节,表示数据发送完毕。
(2) 接收到这个FIN的对端执行 “被动关闭”(passive close),这个FIN由TCP确认。
(3) 一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的TCP也发送一个FIN。
(4) 接收这个最终FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN。
扯了那么多 还没讲到C#的socket网络编程…下面正式开始…
Socket(套接字)编程(TCP)
使用TCP协议通讯需要具备以下几个条件:
(1).建立一个套接字(Socket)
(2).绑定服务器端IP地址及端口号–服务器端
(3).利用Listen()方法开启监听–服务器端
(4).利用Accept()方法与服务器建立连接–客户端
(5).利用Send()方法向建立连接的主机发送消息
(6).利用Receive()方法接受来自建立连接的主机的消息(可靠连接)
流程图:
具体代码实现:(打开两个VS2017)
服务器端:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace Socket编程_TCP_服务器端
{
class Program
{
static void Main(string[] args)
{
//1.创建Socket
Socket tcpServer=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//2.绑定IP和端口号 XXX.XXX.X.XXX
//自行在cmd中输入ipconfig查询ip地址
IPAddress ipAddress=new IPAddress(new byte[]{XXX,XXX,X,XXX4});//字节形式保存
EndPoint point = new IPEndPoint(ipAddress, 7788);//参数为ipAddress和自己设置的端口号 尽量设置成4位数
tcpServer.Bind(point);//向操作系统申请一个可用的IP和端口号 用来做通信
Console.WriteLine("成功绑定IP");
//3.开始监听(等待客户端连接)
tcpServer.Listen(100);//最大连接100个
//4.获取客户端socket
Socket clientSocket= tcpServer.Accept();//暂停当前线程,直到有一个客户端连接进来,再进行下面的代码
Console.WriteLine("客户端已经连接进入");
string message = "欢迎连接到我的服务器";
byte[] data= Encoding.UTF8.GetBytes(message);//将字符串转换成字节形式
clientSocket.Send(data);//发送数据到连接进来的客户端
Console.WriteLine("信息发送成功");
byte[] receiveData=new byte[1024];//创建一个字节数组用来当作容器,去承接客户端发过来的数据
int length= clientSocket.Receive(receiveData);
string receiveMessage = Encoding.UTF8.GetString(receiveData, 0, length);//把接收到的字节数组转换成字符串
Console.WriteLine(receiveMessage);
Console.ReadKey();
}
}
}
客户端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace Socket编程_tcp_客户端
{
class Program
{
static void Main(string[] args)
{
//1.创建客户端Socket
Socket clientSocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//2.发起建立连接的请求
IPAddress ipAddress=IPAddress.Parse("XXX.XXX.X.XXX");//可以把一个字符串的IP地址转换成一个ipaddress的对象
EndPoint point=new IPEndPoint(ipAddress,7788);
clientSocket.Connect(point);
Console.WriteLine("成功连接服务器");
byte[] data=new byte[1024];//保存服务器发送的数据
//length返回值表示接受了多少字节的数据
int length=clientSocket.Receive(data);//这里传递一个byte数组,实际上这个data数组来接受数据
string message=Encoding.UTF8.GetString(data,0,length);//我们实际只要开始从索引为0的数组数据,长度为length的数据
Console.WriteLine(message);
//向服务器发送消息
string message2 = Console.ReadLine();
clientSocket.Send(Encoding.UTF8.GetBytes(message2));//把字符串转换成字节数组发送至服务器端
Console.ReadKey();
}
}
}
以上就是TCP的连接
当然C#也是有UDP连接的,这里就不作展开了
附上两者的区别吧!
1.基于连接于无连接.
2.对系统资源的要求(TCP较多,UDP少).
3.UDP程序结构教简单.
4.流模式与数据报模式.
5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证
最后有一个利用Unity制作客户端,VS2017创建服务器端制作的一个小型聊天室
github连接:https://github.com/oldwang-3gold/Unity_Chat_TCP/