(all notes are from C# official documents) address)
Network related common interfaces
Get local IP
//Obtain IP through network interface description public static string GetLocalIP_LAN80211() { //GetAllNetworkInterfaces returns an object describing the network interface on the local computer. foreach (var interfaces in NetworkInterface.GetAllNetworkInterfaces()) { //The type of NetworkInterfaceType network interface. The Wireless80211 network interface uses wireless LAN connection (IEEE 802.11 standard). //OperationalStatus specifies the operation status of the network interface. The Up network interface is running and can transmit packets. if (interfaces.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 && interfaces.OperationalStatus == OperationalStatus.Up) { //GetIPProperties returns an object that describes the configuration of this network interface. //IPInterfaceProperties provides information about network interfaces that support Internet Protocol version 4 (IPv4) or internet protocol version 6 (IPv6). //UnicastAddresses gets the unicast address assigned to this interface. foreach (var ip in interfaces.GetIPProperties().UnicastAddresses) { //Address of InterNetwork IP version 4. Address of InterNetworkV6 IP version 6. if (ip.Address.AddressFamily == AddressFamily.InterNetwork) { //192. At the beginning, it is guaranteed to obtain the intranet address if (ip.Address.ToString().StartsWith("192.")) return ip.Address.ToString(); } } } } return string.Empty; }
//Resolve local IP through DNS public static string GetLocalIP_V2() { try { //Gets the host name of the local computer. string HostName = Dns.GetHostName(); //Resolve the host name or IP address to an IPHostEntry instance. IPHostEntry IpEntry = Dns.GetHostEntry(HostName); //AddressList gets or sets the list of IP addresses associated with the host. for (int i = 0; i < IpEntry.AddressList.Length; i++) { //Filter out IPv4 type IP addresses from the IP address list //AddressFamily.InterNetwork indicates that this IP is IPv4, //AddressFamily.InterNetworkV6 indicates that this address is IPv6 type if (IpEntry.AddressList[i].AddressFamily == AddressFamily.InterNetwork) { string ip = ""; ip = IpEntry.AddressList[i].ToString(); return IpEntry.AddressList[i].ToString(); } } return ""; } catch (Exception ex) { return ex.Message; } }
UDP
namespace System.Net.Sockets
class UdpClient
brief introduction
Detailed description (forwarding)
Simply put, transport layer, connectionless, unreliable, broadcast multicast solution
initialization
- UdpClient constructor (commonly used and other constructors)
- UdpClient()
To use this constructor, you need to call Connect Method to specify the remote host - UdpClient(Int32)
The parameter is the port number to be bound. Use this constructor to accept all broadcasts on the same port - UdpClient(IPEndPoint)
The parameter is the IP address to be bound. Use this constructor to receive only the broadcast of the incoming IP
- UdpClient()
(if receiving broadcast is not considered, the sender can set a port at will)
use
- Broadcast
method UdpClient.Send
If it is a udp object created by UdpClient() parameterless constructor, you can only call Connect first and then Send(Byte[], Int32) to broadcast
In other cases, Send(Byte[], Int32, IPEndPoint) is called to broadcast. The last parameter is the IP and port specified for broadcasting - Receive broadcast
UdpClient.Receive(IPEndPoint)
If the thread needs to be opened, it will block
UdpClient.ReceiveAsync
(invincible in the world!)
public async void ListenAsync() { while (true) { if (udpClient != null) { try { OnGetMessage(await udpClient.ReceiveAsync()); } catch { break; } } } } private void OnGetMessage(UdpReceiveResult receive) { string msg = Encoding.UTF8.GetString(receive.Buffer); //UnityEngine.Debug.Log($"OnGetMessage ip:{receive.RemoteEndPoint} msg:{msg}"); EventOnGetMessage?.Invoke(receive.RemoteEndPoint, msg); }
If asynchronous execution is performed, call UdpClient. After close, an error will be reported in the await line of code, but it seems to have no impact on the function
Socket
brief introduction
Detailed description (forwarding)
Relationship between Socket and TCP/IP
Tell a joke
Q: what is the relationship between socket and websocket?
A: the relationship between java and JavaScript is the same.
namespace System.Net.Sockets
class Socket
Server
- create object
try { //1.0 instantiation socket (IP4 search protocol, streaming protocol, TCP protocol) _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //IP is local IP and port IPAddress ip = IPAddress.Parse(IP); IPEndPoint endPoint = new IPEndPoint(ip, Port); //Bind socket _socket.Bind(endPoint); //Set maximum number of links _socket.Listen(MaxValue); //Start listening ListenClientConnectAsync(); } catch (Exception e) { Console.WriteLine(e.ToString()); throw; }
- Listen for client links
Socket clientSocket = await _socket.AcceptAsync();
Both a synchronous (blocking) and an asynchronous are Socket objects that provide operations on newly accessed clients. In other words, each obtained Socket corresponds to a connected client. To receive and send client messages, you need to operate the specified Socket object.
- Receive client information
Socket.Receive
After the client disconnects the link abnormally, it will keep receiving null characters, and the client link state is judged manuallyprivate void ReceiveMessage(object socket) { Socket clientSocket = socket as Socket; string tmpIP = clientSocket.RemoteEndPoint.ToString(); if (clientSocket != null) dicClientSocket.Add(tmpIP, clientSocket); while (clientSocket != null&&clientSocket.Connected) { try { int length = clientSocket.Receive(buffer); string msg = Encoding.UTF8.GetString(buffer, 0, length); if (!CheckSocketIsConnect(clientSocket)) throw new Exception("Broken link"); //Client message event received OnGetMsg(clientSocket.RemoteEndPoint.ToString(), msg); } catch (Exception e) { if (clientSocket != null) { //Client disconnect event OnClientDisconnect(tmpIP); dicClientSocket.Remove(tmpIP); //clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close(); clientSocket = null; } break; } } }
ReceiveAsync method can't directly await, so it's not very convenient, so thread Start(clientSocket); - Send information to clients
Socket.Send
If you want to send the content to byte[] and then call send, it will be done.
client
- Connect server
public void StartClient() { try { //1.0 instantiated socket (IP4 addressing address, streaming, TCP protocol) _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //The IP is the server IP, and the port is IPAddress ip = IPAddress.Parse(IP); IPEndPoint endPoint = new IPEndPoint(ip, Port); //Establish link _socket.Connect(endPoint); Thread thread = new Thread(ReceiveMessage); thread.Start(_socket); } catch (Exception e) { UnityEngine.Debug.LogError("link failure : " + e); throw; } }
- Receiving and sending messages
It is the same as sending and receiving messages from the server to the Socket
Disconnect Socket link
First judge whether it is a connection state. If so, call it first Socket.Shutdown(SocketShutdown) break link
Then call Socket.Close
try { aSocket.Shutdown(SocketShutdown.Both); } finally { aSocket.Close(); }
Judge whether the Socket is connected
Socket.Poll(Int32, SelectMode)
Socket.Connected
public static bool CheckSocketIsConnect(Socket socket) { if (socket == null) return false; //SelectRead true if listen has been called and there is a pending connection. //-Or - true if there is data to read. //-Or - returns true if the connection has been closed, reset, or terminated; Otherwise, false is returned. bool part1 = socket.Poll(1000, SelectMode.SelectRead); //Gets the amount of data that has been received from the network and is available for reading. bool part2 = socket.Available == 0; if ((part1 && part2) || !socket.Connected) return false; else return true; }
LAN chat implementation
Use the same router or the same mobile hotspot
- Pure udp implementation
- Everyone can broadcast udp directly
- Socket implementation. udp broadcast server IP, others socket link to the server
- Wait 1 to 2 seconds after opening the application to see if the server IP broadcast is received
- If the broadcast is received, access the server
- If not, initialize the server and broadcast your IP address
- The server forwards the message sent by the client to other clients
- Wait 1 to 2 seconds after opening the application to see if the server IP broadcast is received