(45)C#网络3 socket
一、TCP传输
using System.Net.Sockets;
1.最基本客户端连服务器
服务端运行后一直处于监听状态,客户端每启动一次服务端就接收一次连接并打印客户端的ip地址和端口号。(服务端的端口号是固定的,客户端端口号是随机生成的)
服务端
static void Main(string[] args) { Int32 port = 8500; IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); //创建监听对象,参数1:IPAddress类的对象,参数2:端口号 TcpListener tcpListener = new TcpListener(ipAddress, port); //开启监听 tcpListener.Start(); Console.WriteLine("服务器端口号:" + port + " 开始监听..."); while (true) { //接收一个tcp类型的客户端连接 TcpClient tcpClient = tcpListener.AcceptTcpClient(); //屏幕打印客户端的IP地址和端口号 Console.WriteLine("客户端:{0},连接到服务端", tcpClient.Client.RemoteEndPoint); } }
客户端
static void Main(string[] args) { Console.WriteLine("启动客户端 ..."); TcpClient client = new TcpClient(); try { // 与服务器连接 client.Connect("localhost", 8500); } catch (Exception ex) { Console.WriteLine(ex.Message); return; } Console.ReadKey(); }
2.服务端与客户端聊天
二、UDP传输
UDP是无连接协议,不需要用listener监听。
UDP传输是对等的没有主次之分
IPEndPoint 类
将网络终结点表示为 IP 地址和端口号
//新实例初始化 IPEndPoint 类具有指定的地址和端号,IPEndPoint(IPAddress, Int32) IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Any, 0); //获取或设置IP地址 iPEndPoint.Address //获取或设置端口号 iPEndPoint.Port
三、Socket
构造函数:
Socket(AddressFamily, SocketType, ProtocolType)
AddressFamily 表示地址族 Socket,一般使用InterNetwork 表示ipv4
SocketType:指定套接字类型的实例 Socket 类表示
ProtocolType: 指定 Socket 类支持的协议
属性
Blocking:是否 Socket 处于阻塞模式。bool
Connected:获取一个值,该值指示是否 Socket 连接到远程主机从上次以来 Send 或 Receive 操作。bool
LocalEndPoint:表示本地ip与端口的组合,在调用bind后设置
RemoteEndPoint:面向连接中,该属性可以获取socket连接中的远程IP和端口,无连接中该属性包含将要和socket通信的默认远程ip和端口,RemoteEndPoint在调用acceppt或conncet后使用。
服务端
class Program { static Socket S; static void Main(string[] args) { Console.WriteLine("启动服务器....."); //参数1寻址方案,参数2套接字类型,参数3协议类型 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //设置IP地址和端口号 IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8500); //把地址绑定到socket对象 socket.Bind(ipEndPoint); //启动监听,并设置连接队列的最大长度 socket.Listen(10); try { //持续监听 while (true) { //等待客户端连接,连接后接收客户端返回一个通信用的socket对象 S = socket.Accept(); Console.WriteLine("客户端 " + S.RemoteEndPoint + " 连接到服务器....."); Thread th = new Thread(receive); th.Start(S); } } catch { } } static void receive(object o) { while (true) { try { byte[] buffer = new byte[1024 * 1024 * 2]; //接收客户端消息读到缓冲区(字节数组类型),返回int字节数 int count = S.Receive(buffer); //防止客户端关闭后进入死循环 if (count == 0) { break; } //将字节数组转成字符串 string str = Encoding.UTF8.GetString(buffer, 0, count); Console.WriteLine("客户端" + str); } catch { } } } static void write() { } }
客户端
class Program { static void Main(string[] args) { string str = string.Empty; Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //连接指定的服务器 socket.Connect("127.0.0.1",8500); Console.WriteLine("连接成功"); while (!str.Equals("exit")) { str = Console.ReadLine(); byte[] buffer = Encoding.UTF8.GetBytes(str); socket.Send(buffer); } Console.ReadKey(); } }
同步TCP编程 与异步TCP编程
因为在这个端口下如果同是来了两个客户端请求,第一个连接得到响应,与服务端建立通讯,而第二个请求就会被一直阻塞直到第一个请求完成操作,各个请求之间就好像排个队,顺序执行,这就是同步