1.3.1 什么是Echo程序

Echo程序是网络编程中最基础的案例。建立网络连接后,客户端向服务端发送一行文本,服务端收到后将文本发送回客户端

1.3.2 客户端代码

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.Net.Sockets;
  4. using UnityEngine;
  5. using UnityEngine.UI;
  6. public class Echo : MonoBehaviour
  7. {
  8. //定义套接字
  9. Socket socket;
  10. //UGUI
  11. public InputField inputField;
  12. public Text text;
  13. /// <summary>
  14. /// 点击连接按钮
  15. /// </summary>
  16. public void Connection()
  17. {
  18. //Socket
  19. socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  20. //Connect
  21. socket.Connect("127.0.0.1", 8888);
  22. }
  23. /// <summary>
  24. /// 点击发送按钮
  25. /// </summary>
  26. public void Send()
  27. {
  28. //Send
  29. string sendStr = inputField.text;
  30. byte[] sendBytes = System.Text.Encoding.Default.GetBytes(sendStr);
  31. socket.Send(sendBytes);
  32. //Recy
  33. byte[] readBuff = new byte[1024];
  34. int count = socket.Receive(readBuff);
  35. string recvStr = System.Text.Encoding.Default.GetString(readBuff, 0, count);
  36. text.text = recvStr;
  37. //close
  38. socket.Close();
  39. }
  40. }

1.3.3 客户端代码知识点

using System.Net.Sockets

创建socket对象

Socket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp)这一行用于创建一个Socket对象,它的三个参数分别代表地址族、套接字类型和协议。
地址族指明使用IPv4还是IPv6,其含义如表1-4所示,本例中使用的是IPv4,即InterNetwork。
SocketType是套接字类型,类型如表1-5所示,游戏开发中最常用的是字节流套接字,即Stream。
ProtocolType指明协议,本例使用的是TCP协议,部分协议类型如表1-6所示。若要使用传输速度更快的UDP协议而不是较为可靠的TCP(回顾1.2.5节的内容),需要更改协议类型“Socket(AddressFamily.InterNetwork,SocketType.Dgram, Protocol-Type.Udp)

连接Connect

客户端通过socket.Connect(远程IP地址,远程端口)连接服务端。Connect是一个阻塞方法,程序会卡住直到服务端回应(接收、拒绝或超时)

发送信息Send

客户端通过socket.Send发送数据,这也是一个阻塞方法。该方法接受一个byte[]类型的参数指明要发送的内容。Send的返回值指明发送数据的长度(例子中没有使用)。程序用System.Text.Encoding.Default.GetBytes(字符串)把字符串转换成byte[]数组,然后发送给服务端

接受信息Receive

客户端通过socket.Receive接收服务端数据。Receive也是阻塞方法,没有收到服务端数据时,程序将卡在Receive不会往下执行。Receive带有一个byte[]类型的参数,它存储接收到的数据。Receive的返回值指明接收到数据的长度。之后使用System.Text.Encoding. Default.GetString(readBuff,0, count)将byte[]数组转换成字符串显示在屏幕上。

关闭连接

Socket.Close();

1.3.6 服务端代码

  1. using System;
  2. using System.Net;
  3. using System.Net.Sockets;
  4. namespace Echo
  5. {
  6. class Program
  7. {
  8. /// <summary>
  9. /// 服务器遵照Socket通信的基本流程,先创建Socket对象,
  10. /// 再调用Bind绑定本地IP地址和端口号,
  11. /// 之后调用Listen等待客户端连接。
  12. /// 最后在while循环中调用Accept应答客户端,回应消息
  13. /// </summary>
  14. /// <param name="args"></param>
  15. static void Main(string[] args)
  16. {
  17. Console.WriteLine("Hello World");
  18. //Socket
  19. Socket listenfd = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  20. //Bind
  21. IPAddress ipAdr = IPAddress.Parse("127.0.0.1"); //地址
  22. IPEndPoint ipEp = new IPEndPoint(ipAdr, 8888); //端口
  23. listenfd.Bind(ipEp); //Socket 绑定
  24. //Listener
  25. listenfd.Listen(0); //backLog指的是指定队列中最多可容纳等待接受的连接数,0表示不限制
  26. Console.WriteLine("服务器启动成功");
  27. while (true)
  28. {
  29. //Accept
  30. Socket connfd = listenfd.Accept();
  31. Console.WriteLine("服务器Accept");
  32. //Receive
  33. byte[] readBuff = new byte[1024];
  34. int count = connfd.Receive(readBuff);
  35. string readStr = System.Text.Encoding.Default.GetString(readBuff, 0, count);
  36. Console.WriteLine("服务器接收" + readStr);
  37. //Send
  38. byte[] sendBytes = System.Text.Encoding.Default.GetBytes(readStr);
  39. connfd.Send(sendBytes);
  40. }
  41. }
  42. }
  43. }

1.3.7 服务端代码知识点

绑定Bind

listenfd.Bind(ipEp)将给listenfd套接字绑定IP和端口。程序中绑定本地地址“127.0.0.1”和8888号端口。127.0.0.1是回送地址,指本地机,一般用于测试。读者也可以设置成真实的IP地址,然后在两台计算机上分别运行客户端和服务端程序。

监听Listen

服务端通过listenfd.Listen(backlog)开启监听,等待客户端连接。参数backlog指定队列中最多可容纳等待接受的连接数,0表示不限制

应答Accept

开启监听后,服务器调用listenfd.Accept()接收客户端连接。本例使用的所有Socket方法都是阻塞方法,也就是说当没有客户端连接时,服务器程序卡在listenfd.Accept()不会往下执行,直到接收了客户端的连接。Accept返回一个新客户端的Socket对象,对于服务器来说,它有一个监听Socket(例子中的listenfd)用来监听(Listen)和应答(Accept)客户端的连接,对每个客户端还有一个专门的Socket(例子中的connfd)用来处理该客户端的数据

IPAddress和IPEndPoint

使用IPAddress指定IP地址,使用IPEndPoint指定IP和端口

System.Text.Encoding.Default.GetString

Receive方法将接收到的字节流保存到readBuff上,readBuff是byte型数组。GetString方法可以将byte型数组转换成字符串。同理,System.Text.Encoding.Default.GetBytes可以将字符串转换成byte型数组