Socket comparison of unity backgammon simple online server python, Java and c# languages

Python side code:

import socket
from threading import Thread
import time
importsys


#Create storage object
class Node:
    def __init__(self):
        self.Name = None # Username
        self.Thr = None # Socket connection object


class TcpServer:
    user_name = {} # Store user information; dict username: Node object

    def __init__(self, port):
        """
        Initialize server object
        port: server port
        """
        self.server_port = port # Server port
        self.tcp_socket = socket.socket() # tcp socket
        self.tcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #Port reuse
        self.tcp_socket.bind(self.server_port)

    def start(self):
        """
        Start the server
        """
        self.tcp_socket.listen(10) #Set the number of connections accepted by the server
        print( "System: Waiting for connection")
        while True:
            try:
                conn, addr = self.tcp_socket.accept() # Listen to the client's address and sent messages
            except KeyboardInterrupt: # Pressing ctrl + c will trigger this exception
                self.tcp_socket.close() # Close the socket
                sys.exit("\\
" + "System: Server exits safely!") # The program exits directly without catching exceptions
            except Exception as e:
                print(e)
                continue

            # Create a thread for the current link
            t = Thread(target=self.do_request, args=(conn, ))
            t.start()

    def do_request(self, conn):
        """
        Listen for messages delivered by the client and send the message to all users
        """
        conn_node = Node()
        while True:
            recv_data = conn.recv(1024).decode('utf-8').strip() # Get the data sent by the client
            info_list = recv_data.split(":")

            if info_list[0] == 'userName':
                # New User Registration
                data_info = info_list[-1] + 'Joined the chat'
                self.send_to_all(data_info)
                conn.send('OK'.encode('utf-8'))
                conn_node.Name = info_list[-1]
                conn_node.Thr = conn
                self.user_name[info_list[-1]] = conn_node

            if info_list[0] == 'Mass':
                # Play chess pieces
                self.send_to_other(conn_node.Name,recv_data)


    def send_to_all(self, msg):
        """
        Send message to all users
        """
        print("send_to_all:", msg)
        for i in self.user_name.values():
            i.Thr.send(msg.encode('utf-8'))

    def send_to_other(self, name, msg):
        """
        Send a message to a user other than the one currently sending the message
        """
        print("send_to_other:", msg)
        for n in self.user_name:
            if n != name:
                self.user_name[n].Thr.send(msg.encode('utf-8'))
            else:
                continue

if __name__ == '__main__':
    HOST = "192.168.10.220"
    POST = 7777
    server = TcpServer((HOST, POST))
    server.start()


Java side code:

package server;

import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ChessServer {
\t
    public static void main(String[] args) {
    ChessServer chessServer = new ChessServer();
    chessServer.init();
    }
    
    //Initialize the server
    private void init() {
        try {
            //Create ServerSocket object and listen to port 9999
            @SuppressWarnings("resource")
ServerSocket serversocket = new ServerSocket(7777);
            System.out.println("----------Server Start----------");
            System.out.println("Start monitoring:");
            //Create a loop so that the main thread continues to listen
            while (true){
            \t
                //Make a block and listen to the client
                Socket socket = serversocket.accept();
                System.out.println("Current socket:" + socket);
                //Create a new thread and pass in the client socket
                ServerThread server = new ServerThread(socket);
                //Start thread
                server.start();
                
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    
    class ServerThread extends Thread{
        //Create a Map collection
        private Map<String,Socket> map = new ConcurrentHashMap<>();
        //Create Socket object
        public Socket socket;
            
        public ServerThread(Socket socket){
            this.socket = socket;
        }
         
        //Rewrite the run method
        public void run(){
     
            try {
                //Get the client's input stream
                @SuppressWarnings("resource")
Scanner scanner=new Scanner(socket.getInputStream());
                String msg=null;
                //Write a loop to continue processing the obtained information
                while (true) {
                    //Determine whether the string is received
                    if(scanner.hasNextLine()){
                        //getting information
                        msg=scanner.nextLine();
                        //Process the string input by the client
                        Pattern pattern=Pattern.compile("\r");
                        Matcher matcher=pattern.matcher(msg);
                        msg=matcher.replaceAll("");
                        
                        if(msg.startsWith("userName:"))
                        {
                            //Split the string from: and store the second half in userName
                            String userName=msg.split(":")[1];
                            //Register the user
                            userEnroll(userName,socket);
                            continue;
                        }
                        if(msg.startsWith("Mass:"))
                        {
                            //Convert Map collection to Set collection
                            Set<Map.Entry<String,Socket>> set=map.entrySet();
                            //Traverse the collection and send messages to all users
                            for(Map.Entry<String,Socket> entry:set)
                            {
                                //Get the client's Socket object
                                Socket client=entry.getValue();

                                //Do not update itself
                                if(client != socket){
                                    System.out.println(entry.getKey());
                                    //Get the output stream of the client
                                    PrintStream printstream=new PrintStream(client.getOutputStream());
                                    //Send information to client
                                    printstream.println(msg);
                                    System.out.println(msg);
                                }
                            }
                        }
                    }
     
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        //registered user
        private void userEnroll(String userName,Socket socket){
            //Add key-value pairs to the Map collection
            map.put(userName,socket);
            //Print log
            System.out.println("[Username" + userName + "][Client is" + socket + "] is online!");
            System.out.println("The accumulated number of people entering is:" + map.size() + "people");
        }
        
    }
}

c# side code:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
#nullable disable
namespace UnityServer
{
    internal class Server
    {
        static string receiveStr = "";
        /// <summary>
        /// Server socket
        /// </summary>
        static Socket serverSocket;
        /// <summary>
        /// Dictionary of client socket and client information
        /// </summary>
        static Dictionary<Socket, ClientState> clients = new Dictionary<Socket, ClientState>();


        public static void Main()
        {
            //Define socket
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //Bind ip and port
            IPAddress ip = IPAddress.Parse("192.168.10.220");
            IPEndPoint iPEndPoint = new IPEndPoint(ip, 7777);
            serverSocket.Bind(iPEndPoint);
            //monitor
            serverSocket.Listen(0);
            Console.WriteLine("----------Server Start----------");
            Console.WriteLine("Start listening:");

            //serverSocket.BeginAccept(AcceptCallback, serverSocket);
            //Console.ReadLine();

            List<Socket> socketList = new List<Socket>();
            while(true)
            {
                socketList.Clear();
                socketList.Add(serverSocket);
                foreach (ClientState s in clients.Values)
                {
                    socketList.Add(s.socket);
                }

                //Detect readable Socket
                Socket.Select(socketList, null, null, 1000);
                foreach (Sockets in socketList)
                {
                    if (s == serverSocket)
                    {
                        Accept(s);
                    }
                    else
                    {
                        Receive(s);
                    }
                }
            }

        }

        /// <summary>
        /// Server Accept
        /// </summary>
        /// <param name="serverSocket"></param>
        private static void Accept(Socket serverSocket)
        {
            Console.WriteLine("Accept");
            Socket clientSocket = serverSocket.Accept();
            ClientState state = new ClientState();
            state.socket = clientSocket;
            clients.Add(clientSocket, state);
        }

        /// <summary>
        /// Receive messages and send to all clients
        /// </summary>
        /// <param name="clientSocket"></param>
        private static void Receive(Socket clientSocket)
        {
            ClientState state = clients[clientSocket];
            int count = clientSocket.Receive(state.readBuff);

            //closure
            if (count == 0)
            {
                clientSocket.Close();
                clients.Remove(clientSocket);
                Console.WriteLine("A client disconnected");

                return;
            }
            //Send to all clients
            receiveStr = Encoding.UTF8.GetString(state.readBuff, 0, count);
            Console.WriteLine("Receive:" + receiveStr);

            MassSend(receiveStr);

        }

        //Send a message
        public static void MassSend(string msg)
        {
            byte[] sendBytes = Encoding.UTF8.GetBytes(msg);
            foreach (ClientState s in clients.Values)
            {
                s.socket.Send(sendBytes);
            }
        }
    }
}

Except for the difference in syntax, the core method is the same, which is to listen to all the socket clients that have joined and send messages to other clients except yourself. Use a collection to store newly added clients, and then distinguish whether the client that wants to receive the message includes itself. First update its own chessboard, and then tell the server to asynchronously update other clients except itself. If there is no distinction between itself and the player currently sending the message (I don’t know which user sent the message). The client’s functions need to be updated synchronously so that the server can update the board status of all players at the same time.