TCP / IP套接字-如何从服务器接收?统一

时间:2018-07-20 16:32:26

标签: c# sockets networking unityscript multiplayer

请给我一些帮助。我正在Unity中创建一个多人游戏。我已使连接正常工作,服务器将消息发送到客户端,然后客户端接收到它们。但是,由于某种原因,我不了解我的服务器没有从客户端收到任何信息。

我要在下面粘贴我的代码。单击主机按钮时,我已经启动了服务器,同时它还启动了一个客户端。非常感谢您的帮助。

非常感谢您

服务器(C#)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using System;  
using System.Net;  
using System.Net.Sockets;  
using System.Text;  
using System.Threading;
using System.IO;

public class myServer1 : MonoBehaviour {

    public int port = 8000;
    string host = "";

    static List<ServerClient> clients;
    static List<ServerClient> disconnectList;

    //creating the socket TCP
    public Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    //create the buffer size, how much info we can send and receive 
    byte[] serverBuffer = new byte[1024];

    bool serverStarted;

    public string content;

    /*instead of creating the server in Start I need to created in aother function, 
    because the server gets called when the player cliks the button "host game" 
    and then wait for more players to join, and we need to change scenes so 
    we don't want to destroy the server after loading the new scene
    */

    public void Init(){
        DontDestroyOnLoad(gameObject); //don't destroy the server once the new scene is loaded

        //instaciating the lists
        clients = new List<ServerClient>();
        disconnectList = new List<ServerClient>();

        try
        {
            //call the function create server here
            CreateServer();
        }
        catch (Exception ex)
        {
            Debug.Log("Error when creating the server: " + ex.Message);
            //Show dialog error to the player
        }
    }


    // Use this for initialization
    void Start () {

        //try
        //{
        //    //start server
        //    CreateServer();
        //}
        //catch (Exception ex)
        //{
        //    Debug.Log("Error when creating the server " + ex.Message);
        //}
    }

    // Update is called once per frame
    void Update () {

        if (!serverStarted)
        {
            return;
        }

        foreach (ServerClient sc in clients)
        {
            // is the client still connected?
            if (!isConnected(sc.tcpSocket))
            {
                sc.tcpSocket.Close(); //close the socket 
                disconnectList.Add(sc);
                continue;
            }
            //check for messages from the client, check the stream of every client
            else // client is connected to the server
            {
                //NetworkStream stream = new NetworkStream(sc.tcpSocket);

                //if (stream.DataAvailable){

                    //StreamReader reader = new StreamReader(stream, true); //reading the data
                    //string data = reader.ReadLine(); //store data

                CheckForData(sc);

                //if there is data



                //}


                AcceptConnections();


            }
        }

        //disconnection loop
        for (int i = 0; i < disconnectList.Count - 1; i++)
        {
            //tell our player somebody has disconnected

            clients.Remove(disconnectList[i]);
            disconnectList.RemoveAt(i);
        }
    }


    // Bind the socket to the local endpoint and listen for incoming connections.  
    public void CreateServer(){
        try
        {
            Debug.Log("Setting up the server...");

            //bind socket
            serverSocket.Bind(new IPEndPoint(IPAddress.Any, port));
            Debug.Log("socket bound");

            //start listening
            serverSocket.Listen(3); //only 3 connections at a time
            Debug.Log("socket listening on port: " + port);

            //accept connections
            AcceptConnections();

            serverStarted = true;
        }
        catch (Exception e)
        {

            Debug.Log("Error when binding to port and listening: " + e.Message);
        }

    }

    //start async socket to listen for connections
    public void AcceptConnections(){

        serverSocket.BeginAccept(AcceptCallback, serverSocket);
    }

    //async socket
    void AcceptCallback(IAsyncResult ar)
    {
        // Get the socket that handles the client request  
        Socket server = (Socket)ar.AsyncState;
        //Socket handler = server.EndAccept(ar);
        ServerClient handler = new ServerClient(server.EndAccept(ar));


        //begin receiving data from the client//////////////////////////////////////
        handler.tcpSocket.BeginReceive( serverBuffer, 0, serverBuffer.Length, 0,  
        ReadCallback, handler);  

        //CheckForData(handler);


        //add client to dictionary key: client value: stake
        clients.Add(handler);

        //accept incoming connections again
        AcceptConnections();

        Debug.Log("Someone has connected!!!!");

        if (clients.Count > 0){
            Debug.Log("client successfully added to the list of clients");
        }

        //send a message to everyone say someone has connected
        BroadCastData("some client has connected", clients);  
    }


    /////////CHECK IF THERE IS DATA TO BE RECEIVED/////////

    public void CheckForData(ServerClient socket){

        //begin receiving data from the client
        socket.tcpSocket.BeginReceive(serverBuffer, 0, serverBuffer.Length, 0,  
                            ReadCallback, socket);

    }

    void ReadCallback(IAsyncResult ar)
    {

        //client socket
        Socket handler = (Socket)ar.AsyncState;
        ServerClient client = new ServerClient(handler);

        Debug.Log("function to read data from client");


        // Read data from the client socket   
        int bytesRead = client.tcpSocket.EndReceive(ar);

        Debug.Log("receiving from client....");


        if (bytesRead == 0)
        {
            //no data to read 
            Debug.Log("no data to receive");
            return;
        }


        //////////////not sure here
        var data = new byte[bytesRead];
        Array.Copy(serverBuffer, data, bytesRead);

        // Get the data  
        client.tcpSocket.BeginReceive(serverBuffer, 0, serverBuffer.Length, 0,
                                      new AsyncCallback(ReadCallback), client.tcpSocket);
        /////////////////

        //store the data received
        content = Encoding.ASCII.GetString(serverBuffer);


        //send data to teh client
        //Send(client.tcpSocket, "hello from the server");

        //OnIncommingData(client, content);

        Debug.Log("client sent: " );

    }

    /////////PROCESS DATA RECEIVED/////////

    public void OnIncommingData(ServerClient client, string data){

        Debug.Log("client has send: " + data);

    }

    /////////SEND DATA PROCESSED BACK TO THE CLIENT/////////

    public void BroadCastData(string data, List<ServerClient> clients){

        foreach (var cl in clients)
        {
            try
            {
                //send data back to client
                Send(cl.tcpSocket, "hello from server");
                Debug.Log("sent a message to the client");
            }
            catch (Exception ex)
            {
                Debug.Log("error writing data: " + ex.Message);
            }
        }

    }

    static void Send(Socket handler, String data)
    {

        // Convert the string data to byte data using ASCII encoding  
        byte[] byteData = Encoding.ASCII.GetBytes(data);

        // Begin sending the data to the remote device  
        handler.BeginSend(byteData, 0, byteData.Length, 0,
            new AsyncCallback(SendCallback), handler);
    }

    static void SendCallback(IAsyncResult ar)
    {

        try
        {
            //client socket 
            Socket handler = (Socket)ar.AsyncState;

            // Complete sending the data to the client  
            int bytesSent = handler.EndSend(ar);

            Debug.Log("bytes sent to the client: " + bytesSent);

            //Debug.Log("clients connected: " + clients[clients.Count - 1].clientName);

        }
        catch (Exception e)
        {
            Debug.Log("error: " + e.Message);
        }
    }



    /////////check if te client is connected to the server/////////

    bool isConnected(Socket c)
    {
        try
        {
            if (c != null && c != null && c.Connected)
            {
                if (c.Poll(0, SelectMode.SelectRead))
                {
                    return !(c.Receive(new byte[1], SocketFlags.Peek) == 0);
                }
                return true;
            }
            return false;
        }
        catch
        {
            return false;
        }
    }


    /////////definition of the client/////////

    public class ServerClient
    {

        public Socket tcpSocket;

        public string clientName;


        public ServerClient(Socket clientSocket)
        {
            tcpSocket = clientSocket;
        }
    }


}

Client(C#)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System;
using System.IO;

public class myClient1 : MonoBehaviour {

    public string clientName;
    private bool socketReady;
    public static string response;
    private static byte[] clientBuffer = new byte[1024];

    //creating the socket TCP
    public Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    //declare end point
    public IPEndPoint conn;


    // Use this for initialization
    void Start () {

        DontDestroyOnLoad(gameObject); //don't destroy the client when moving on to the next scene
    }

    // Update is called once per frame
    void Update () {

        if (socketReady)
        {
            //check for new messages
            CheckForData(clientSocket);

            //Debug.Log("socket ready");

        }

    }

    public bool ConnectToServer(string hostAdd, int port)
    {
        //if already connected ignore this fucntion 
        if (socketReady)
        {
            return false;
        }

        //connect the socket to the server
        try
        {
            //create end point to connect
            conn = new IPEndPoint(IPAddress.Parse(hostAdd), port);
            //connect to server
            clientSocket.BeginConnect(conn, ConnectCallback, clientSocket);
            socketReady = true;
            Debug.Log("Client socket ready: "+ socketReady);

            // Send test data to the remote device.  
            SendData(clientSocket, "This is a test");
            Debug.Log("message sent to the server");


            // Receive the response from the remote device.  
            //ReceiveData(clientSocket);

            CheckForData(clientSocket);

            // Write the response to the console

        }
        catch (Exception ex)
        {
            Debug.Log("socket error: " + ex.Message);
        }

        return socketReady;
    }


    //async call to connect
    static void ConnectCallback(IAsyncResult ar)
    {
        try
        {

            // Retrieve the socket 
            Socket client = (Socket)ar.AsyncState;

            // Complete the connection  
            client.EndConnect(ar);

            //Debug.Log("Client successfully connected!!!!!");
            Debug.Log("Client Socket connected to: " + client.RemoteEndPoint);

        }
        catch (Exception e)
        {
            Debug.Log("Error connecting: " + e);
        }
    }


    /////////SEND DATA TO THE SERVER/////////
    //send data to server
    public static void SendData(Socket client, string data)
    {
        //convert the string data to bytes
        byte[] byteData = Encoding.ASCII.GetBytes(data);

        // Begin sending the data to the remote device.  
        client.BeginSend(byteData, 0, byteData.Length, 0,
            new AsyncCallback(SendCallBack), client);
    }

    static void SendCallBack(IAsyncResult ar)
    {
        try
        {
            Socket client = (Socket)ar.AsyncState;

            //send date to the server
            int bytesSent = client.EndSend(ar);

            Debug.Log("client sent: " + bytesSent);
        }
        catch (Exception e)
        {
            Debug.Log("error sending message: " + e);
        }
    }
    //enclose this in one function 


    /////////RECEIVE DATA FROM THE SERVER/////////

    //process the data received
    void OnIncomingData(string data)
    {
        Debug.Log("server answer: " + data);



    }

    public static void CheckForData(Socket client){

        try
        {
            // Begin receiving the data from the remote device.  
            client.BeginReceive(clientBuffer, 0, clientBuffer.Length, 0,
                                new AsyncCallback(ReceiveCallback), client);
        }
        catch (Exception e)
        {
            Debug.Log("error receiving the data: " + e.Message);
        }

    }

    static void ReceiveCallback(IAsyncResult ar)
    {
        try
        {
            // Read data from the remote device.  
            Socket client = (Socket)ar.AsyncState;
            int bytesRead = client.EndReceive(ar);

            //don't know why after receiving my info this gets called. 
            if (bytesRead == 0)
            {
                Debug.Log("no more data to receive");
                return;
            }

            var data = new byte[bytesRead];
            Array.Copy(clientBuffer, data, bytesRead);

            // Get the data  
            client.BeginReceive(clientBuffer, 0, clientBuffer.Length, 0,
                                new AsyncCallback(ReceiveCallback), client);

            response = Encoding.Default.GetString(clientBuffer);

            Debug.Log("data from server received in the client: " + response);

        }
        catch (Exception ex)
        {
            Debug.Log("Error: " + ex.Message);
        }
    }



    /////////CLOSES THE SOCKET/////////
    void OnApplicationQuit()
    {
        CloseSocket();
    }

    void OnDisable()
    {
        CloseSocket();
    }


    void CloseSocket()
    {

        if (!socketReady)
        {
            return;
        }

        clientSocket.Close();
        socketReady = false;
    }



    public class GameClient
    {
        public string name;
        public bool isHost;
    }

}

0 个答案:

没有答案