当前位置:   article > 正文

unity五子棋简单联机服务端python、Java和c#语言的socket对比_c#实现五子棋联机

c#实现五子棋联机

python端代码:

import socket
from threading import Thread
import time
import sys


# 创建存储对象
class Node:
    def __init__(self):
        self.Name = None    # 用户名
        self.Thr = None     # 套接字连接对象


class TcpServer:
    user_name = {}  # 存储用户信息; dict 用户名:Node对象

    def __init__(self, port):
        """
        初始化服务器对象
        port:   服务器端口
        """
        self.server_port = port      # 服务器端口
        self.tcp_socket = socket.socket()       # tcp套接字
        self.tcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)       # 端口重用
        self.tcp_socket.bind(self.server_port)

    def start(self):
        """
        启动服务器
        """
        self.tcp_socket.listen(10)      # 设置服务器接受的链接数量
        print( "系统:等待连接")
        while True:
            try:
                conn, addr = self.tcp_socket.accept()       # 监听客户端的地址和发送的消息
            except KeyboardInterrupt:       # 按下ctrl+c会触发此异常
                self.tcp_socket.close()     # 关闭套接字
                sys.exit("\n" + "系统:服务器安全退出!")        # 程序直接退出,不捕捉异常
            except Exception as e:
                print(e)
                continue

            # 为当前链接创建线程
            t = Thread(target=self.do_request, args=(conn, ))
            t.start()

    def do_request(self, conn):
        """
        监听客户端传送的消息,并将该消息发送给所有用户
        """
        conn_node = Node()
        while True:
            recv_data = conn.recv(1024).decode('utf-8').strip()     # 获取客户端发来的数据
            info_list = recv_data.split(":")

            if info_list[0] == 'userName':
                # 新用户注册
                data_info = info_list[-1] + '加入了聊天'
                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':
                # 下棋子
                self.send_to_other(conn_node.Name,recv_data)


    def send_to_all(self, msg):
        """
        对所有用户发送消息
        """
        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):
        """
        对除了当前发送信息的用户外的其他用户发送消息
        """
        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()


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95

Java端代码:

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 {
	
    public static void main(String[] args) {
    	ChessServer chessServer = new ChessServer();
    	chessServer.init();
    }
    
    //初始化服务器
    private void init() {
        try {
            //创建ServerSocket对象,监听9999端口
            @SuppressWarnings("resource")
			ServerSocket serversocket = new ServerSocket(7777);
            System.out.println("----------服务器启动----------");
            System.out.println("开始监听:");
            //创建一个循环,使主线程持续监听
            while (true){
            	
                //做一个阻塞,监听客户端
                Socket socket = serversocket.accept();
                System.out.println("当前socket:" + socket);
                //创建一个新的线程,将客户端socket传入
                ServerThread server = new ServerThread(socket);
                //启动线程
                server.start();
                
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    
    class ServerThread extends Thread{
        //创建一个Map集合
        private Map<String,Socket> map = new ConcurrentHashMap<>();
        //创建Socket对象
        public Socket socket;
            
        public ServerThread(Socket socket){
            this.socket = socket;
        }
         
        //重写run方法
        public void run(){
     
            try {
                //获取客户端的输入流
                @SuppressWarnings("resource")
				Scanner scanner=new Scanner(socket.getInputStream());
                String msg=null;
                //写一个循环来持续处理获取到的信息
                while (true) {
                    //判断是否接收到了字符串
                    if(scanner.hasNextLine()){
                        //获取信息
                        msg=scanner.nextLine();
                        //处理客户端输入的字符串
                        Pattern pattern=Pattern.compile("\r");
                        Matcher matcher=pattern.matcher(msg);
                        msg=matcher.replaceAll("");
                        
                        if(msg.startsWith("userName:"))
                        {
                            //将字符串从:拆分开,后半部分存入userName中
                            String userName=msg.split(":")[1];
                            //注册该用户
                            userEnroll(userName,socket);
                            continue;
                        }
                        if(msg.startsWith("Mass:"))
                        {
                            //将Map集合转换为Set集合
                            Set<Map.Entry<String,Socket>> set=map.entrySet();
                            //遍历集合,向所有用户发送消息
                            for(Map.Entry<String,Socket> entry:set)
                            {
                                //取得客户端的Socket对象
                                Socket client=entry.getValue();

                                //不更新自己
                                if(client != socket){
                                    System.out.println(entry.getKey());
                                    //取得client客户端的输出流
                                    PrintStream printstream=new PrintStream(client.getOutputStream());
                                    //向客户端发送信息
                                    printstream.println(msg);
                                    System.out.println(msg);
                                }
                            }
                        }
                    }
     
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        //注册用户
        private void userEnroll(String userName,Socket socket){
            //将键值对添加入Map集合中
            map.put(userName,socket);
            //打印日志
            System.out.println("[用户名为"+userName+"][客户端为"+socket+"]上线了!");
            System.out.println("积累进入人数为:"+map.size()+"人");        
        }
        
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122

c#端代码:

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>
        /// 服务端socke
        /// </summary>
        static Socket serverSocket;
        /// <summary>
        /// 客户端socket以及客户端信息的字典
        /// </summary>
        static Dictionary<Socket, ClientState> clients = new Dictionary<Socket, ClientState>();


        public static void Main()
        {
            //定义socket
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //绑定ip和端口
            IPAddress ip = IPAddress.Parse("192.168.10.220");
            IPEndPoint iPEndPoint = new IPEndPoint(ip, 7777);
            serverSocket.Bind(iPEndPoint);
            //监听
            serverSocket.Listen(0);
            Console.WriteLine("----------服务器启动----------");
            Console.WriteLine("开始监听:");

            //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);
                }

                //检测可读Socket
                Socket.Select(socketList, null, null, 1000);
                foreach (Socket s in socketList)
                {
                    if (s == serverSocket)
                    {
                        Accept(s);
                    }
                    else
                    {
                        Receive(s);
                    }
                }
            }

        }

        /// <summary>
        /// 服务端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>
        /// 接收消息以及发送给所有客户端
        /// </summary>
        /// <param name="clientSocket"></param>
        private static void Receive(Socket clientSocket)
        {
            ClientState state = clients[clientSocket];
            int count = clientSocket.Receive(state.readBuff);

            //关闭
            if (count == 0)
            {
                clientSocket.Close();
                clients.Remove(clientSocket);
                Console.WriteLine("有一个客户端断开连接");

                return;
            }
            //发送给所有客户端
            receiveStr = Encoding.UTF8.GetString(state.readBuff, 0, count);
            Console.WriteLine("Receive:" + receiveStr);

            MassSend(receiveStr);

        }

        //发送消息
        public static void MassSend(string msg)
        {
            byte[] sendBytes = Encoding.UTF8.GetBytes(msg);
            foreach (ClientState s in clients.Values)
            {
                s.socket.Send(sendBytes);
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117

除了语法有区别,核心方法是一样的,监听所有加入的socket端客户,发送消息给除自己外的其它客户端。用一个集合存放新加入的客户端,然后区分要收消息的客户端是否包含自己,先更新自身棋盘,再告诉服务器异步更新除自己外的其他客户端,如果没有区分自己和当前发送消息的玩家(不知道是哪个用户发送的消息),客户端的功能需要同步更新让服务器同时更新所有玩家棋盘状态。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/116555?site
推荐阅读
相关标签
  

闽ICP备14008679号