0

我一直在编写一个由两部分组成的聊天程序:服务器和客户端。服务器用于TcpListener监听传入请求以加入服务器,客户端使用TcpClient它连接到服务器并发送消息。到目前为止,我的握手是客户端连接时发送的第一条消息——它包含客户端的 IP 地址和昵称集。我不知道如何让服务器异步侦听,因为如果它不是异步的,那么聊天将是client -> server -> client -> server而它需要一次连接到多个客户端,并一次接收多条消息。到目前为止,我的代码是同步编写的:
客户端:

public void StartClient(string serverIP)
{
    ReadWrite rw = new ReadWrite();
    string nick = rw.GetNick();
    string handshakeContents = "HANDSHAKE:" + nick + ":" + GetIP();
    Int32 serverPort = 1336; // yay
    TcpClient client = new TcpClient(serverIP, serverPort);
    Console.WriteLine("Sending initial handshake: {0}", handshakeContents);
    Byte[] data = System.Text.Encoding.ASCII.GetBytes(handshakeContents); // Convert handshakeContents to Byte[]
    NetworkStream stream = client.GetStream(); // Instantiate object "stream" for use in read/write
    stream.Write(data, 0, data.Length); // Send handshakeContents in Byte[] to server
    Console.WriteLine(" - Connecting to IlanChat Server on ip {0}", serverIP);
    Thread.Sleep(1000); // sleep 1s
    data = new Byte[256];
    string responseHandshake = String.Empty; // response handshake from server
    Int32 bytes = stream.Read(data, 0, data.Length); // Read handshake.
    responseHandshake = System.Text.Encoding.ASCII.GetString(data, 0, bytes); // Decode from Byte[] to ASCII string
    Console.WriteLine(" -  Received response handshake: {0}", responseHandshake);
    Console.WriteLine(" - Successfully connected to IlanChat server on IP {0}", serverIP); // display message
    Thread.Sleep(2000);
    Console.Clear();
    List<string> messagesRecieved = new List<string>();
    while(true)
    {
        Console.Clear();
        foreach (string msg in messagesRecieved)
        {
            Console.WriteLine(msg);
        }
        Console.WriteLine();
        Console.Write("Enter message: ");
        string msgRaw = Console.ReadLine();
        string sendMsg = nick + ": " + msgRaw;
        data = new Byte[256];
        data = System.Text.Encoding.ASCII.GetBytes(sendMsg);
        stream.Write(data, 0, data.Length); // finish this async shit
    }
}

服务器:

        List<string> clientIP = new List<string>();
        List<string> clientNicks = new List<string>();
        string responseHandshake = "hello";
        Int32 serverPort = 1336;
        IPAddress machineIP = IPAddress.Parse(GetIP());
        Console.Clear();
        Console.WriteLine(" - Starting IlanChat server on IP {0}", machineIP);
        TcpListener server = null;
        server = new TcpListener(machineIP, serverPort);
        server.Start();
        Byte[] buffer = new Byte[256];
        String data = null;
        Console.WriteLine("Successfully started IlanChat server!");
        while (true) // first alpha - only one user at a time
        {
            Console.WriteLine();
            Console.WriteLine("Waiting for connections..");
            TcpClient client = server.AcceptTcpClient();
            Console.WriteLine("User connecting..");
            Console.WriteLine("Receiving handshake data..");
            data = null;
            NetworkStream stream = client.GetStream();
            int i;
            while ((i = stream.Read(buffer, 0, buffer.Length)) != 0)
            {
                data = System.Text.Encoding.ASCII.GetString(buffer, 0, i);
                Console.WriteLine("Received handshake data: {0}", data);
                Console.WriteLine("Processing data.."); // sample handshake: - HANDSHAKE:nick:ip
                string tempNick = data.Replace("HANDSHAKE:", "");
                string[] userDetails = tempNick.Split(':'); // should store to 0:nick, 1:ip
                Console.WriteLine("Received client nick: {0}", userDetails[0]);
                Console.WriteLine("Received client IP: {0}", userDetails[1]);
                break;
            }
            Thread.Sleep(1100); // sleep
            buffer = System.Text.Encoding.ASCII.GetBytes(responseHandshake);
            Console.WriteLine("Sending response handshake..");
            stream.Write(buffer, 0, buffer.Length);
        }

有没有办法让服务器一次接受多个连接并维护它们?有没有办法让客户端一次接收多条消息并在刷新消息时输入?

4

1 回答 1

1

您需要考虑使用线程(任务库,异步/等待)来做您想做的事情。试试看这里:

https://codereview.stackexchange.com/questions/29000/c-console-chat-server-async-await-tcpclient-tcplistener-networkstream-asyn

为了让您开始,假设您的代码中的逻辑是正确的,您希望拆分服务器/客户端,如下所示:

static void RunServer()
        {
            List<string> clientIP = new List<string>();
            List<string> clientNicks = new List<string>();
            string responseHandshake = "hello";
            Int32 serverPort = 1336;
            IPAddress machineIP = IPAddress.Parse(GetIP());
            Console.Clear();
            Console.WriteLine(" - Starting IlanChat server on IP {0}", machineIP);
            TcpListener server = null;
            server = new TcpListener(machineIP, serverPort);
            server.Start();
            Byte[] buffer = new Byte[256];
            String data = null;
            Console.WriteLine("Successfully started IlanChat server!");
            while (true) // first alpha - only one user at a time
            {
                Console.WriteLine();
                Console.WriteLine("Waiting for connections..");
                TcpClient client = server.AcceptTcpClient();

                Task.Run(() => RunClient(client));
            }
        }

        static void RunClient(TcpClient client)
        {
            Byte[] buffer = new Byte[256];
            Console.WriteLine("User connecting..");
            Console.WriteLine("Receiving handshake data..");
            String data = null;
            string responseHandshake = "hello";

            NetworkStream stream = client.GetStream();
            int i;
            while ((i = stream.Read(buffer, 0, buffer.Length)) != 0)
            {
                data = System.Text.Encoding.ASCII.GetString(buffer, 0, i);
                Console.WriteLine("Received handshake data: {0}", data);
                Console.WriteLine("Processing data.."); // sample handshake: - HANDSHAKE:nick:ip
                string tempNick = data.Replace("HANDSHAKE:", "");
                string[] userDetails = tempNick.Split(':'); // should store to 0:nick, 1:ip
                Console.WriteLine("Received client nick: {0}", userDetails[0]);
                Console.WriteLine("Received client IP: {0}", userDetails[1]);
                break;
            }
            Thread.Sleep(1100); // sleep
            buffer = System.Text.Encoding.ASCII.GetBytes(responseHandshake);
            Console.WriteLine("Sending response handshake..");
            stream.Write(buffer, 0, buffer.Length);
        }
于 2013-11-11T10:32:29.883 回答