具有多个客户端的异步套接字服务器

时间:2017-09-21 14:32:33

标签: c# sockets

我有一个问题我无法解决,因为我的c#知识不是很好。 我在互联网上找到了一些代码,并根据我的需要进行了修改。

我的问题是,当我向客户发送消息时,只有一个接收消息,然后另一个客户端接收下一个消息,依此类推。 我希望向所有连接的客户端发送相同的消息,而不会丢失任何数据。

服务器

using System;
using System.Net.Sockets;
using System.Threading;


public class AsynchIOServer
{
    static TcpListener tcpListener = new TcpListener(10);

    static void Listeners()
    {

        Socket socketForClient = tcpListener.AcceptSocket();
        if (socketForClient.Connected)
        {
            Console.WriteLine("Client:"+socketForClient.RemoteEndPoint+" now connected to server.");
            NetworkStream networkStream = new NetworkStream(socketForClient);
            System.IO.StreamWriter streamWriter =
            new System.IO.StreamWriter(networkStream);
            System.IO.StreamReader streamReader =
            new System.IO.StreamReader(networkStream);

            ////here we send message to client
            while (true){
                Console.WriteLine("type your message to be recieved by client:");
                string theString = Console.ReadLine();
                streamWriter.WriteLine(theString);
                ////Console.WriteLine(theString);
                streamWriter.Flush();
            }
            streamReader.Close();
            networkStream.Close();
            streamWriter.Close();

        }
        socketForClient.Close();
        Console.WriteLine("Press any key to exit from server program");
        Console.ReadKey();
    }

    public static void Main()
    {
        //TcpListener tcpListener = new TcpListener(10);
        tcpListener.Start();
        Console.WriteLine("************This is Server program************");
        Console.WriteLine("Hoe many clients are going to connect to this server?:");
        int numberOfClientsYouNeedToConnect =int.Parse( Console.ReadLine());
        for (int i = 0; i < numberOfClientsYouNeedToConnect; i++)
        {
            Thread newThread = new Thread(new ThreadStart(Listeners));
            newThread.Start();
        }
    }
}

客户端:

using System;
using System.Net.Sockets;
using System.Threading;
public class Client
{
    static public void Main(string[] Args)
    {
        TcpClient socketForServer;
        try
        {
            socketForServer = new TcpClient("localHost", 10);
        }
        catch
        {
            Console.WriteLine(
            "Failed to connect to server at {0}:999", "localhost");
            return;
        }

        NetworkStream networkStream = socketForServer.GetStream();
        System.IO.StreamReader streamReader =
        new System.IO.StreamReader(networkStream);
        System.IO.StreamWriter streamWriter =
        new System.IO.StreamWriter(networkStream);
        Console.WriteLine("*******This is client program who is connected to localhost on port No:10*****");

            try
            {
                string outputString;
            // read the data from the host and display it
            {
                while (true)
                {
                    outputString = streamReader.ReadLine();
                    Console.WriteLine("Message Recieved by server:" + outputString);

                    streamWriter.Flush();
                }
            }
        }
            catch
            {
                Console.WriteLine("Exception reading from Server");
            }
        // tidy up
        networkStream.Close();
        Console.WriteLine("Press any key to exit from client program");
        Console.ReadKey();
    }

    private static string GetData()
    {
        //Ack from sql server
        return "ack";
    }
}

谢谢

2 个答案:

答案 0 :(得分:1)

你的代码错了。

首先,我将为您提供一些有关其错误以及为何无法按照您想要的方式工作的见解。

您正在创建n个线程,并使它们全部等待连接。如果耗尽线程数怎么办?如果其中任何一个意外退出会怎么样?

您也发送错误的数据。通过使用{{1}},您不会通过多个线程传递数据并读取每个线程中的行,而是调用Console.ReadLine的第一个将是将要​​接收它的那个线程。 。这意味着您只会发送一个Socket。

你如何管理它并不理想。在线提供数十个甚至数百个多线程套接字服务器/客户端,我邀请您进行更多研究。但首先,我希望您在C#中更多地研究线程/任务。

答案 1 :(得分:0)

简单的多线程服务器:

    static void Process(Socket client) {

        Console.WriteLine("Incoming connection from " + client.RemoteEndPoint);

        const int maxMessageSize = 1024;
        byte[] response;
        int received;

        while (true) {

            // Send message to the client:
            Console.Write("Server: ");
            client.Send(Encoding.ASCII.GetBytes(Console.ReadLine()));
            Console.WriteLine();

            // Receive message from the server:
            response = new byte[maxMessageSize];
            received = client.Receive(response);
            if (received == 0) {
                Console.WriteLine("Client closed connection!");
                return;
            }

            List<byte> respBytesList = new List<byte>(response);
            respBytesList.RemoveRange(received, maxMessageSize - received); // truncate zero end
            Console.WriteLine("Client (" + client.RemoteEndPoint + "+: " + Encoding.ASCII.GetString(respBytesList.ToArray()));
        }
    }

    static void Main(string[] args) {

        int backlog = -1, port = 2222;

        Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        server.ReceiveTimeout = -1;

        // Start listening.
        try {
            server.Bind(new IPEndPoint(IPAddress.Any, port));
            server.Listen(backlog);
        }
        catch (Exception) {
            Console.WriteLine("Listening failed!");
            Console.ReadKey();
            return;
        }

        Console.WriteLine("Start listening...");

        while(true) {
            Socket client = server.Accept();
            new System.Threading.Thread(() => {
                try { Process(client); } catch (Exception ex) { Console.WriteLine("Client connection processing error: " + ex.Message); }
            }).Start();
        }

        //Console.WriteLine("Press any key for exit...");
        //Console.ReadKey();
    }

客户:

    static void WorkWithServer(Socket server) {

        const int maxMessageSize = 1024;
        byte[] response;
        int received;

        while(true) {

            try {

                // Receive message from the server:
                response = new byte[maxMessageSize];
                received = server.Receive(response);
                if (received == 0) {
                    Console.WriteLine("Server closed connection.");
                    return;
                }

                List<byte> respBytesList = new List<byte>(response);
                respBytesList.RemoveRange(received, maxMessageSize - received); // truncate zero end
                Console.WriteLine("Server: " + Encoding.ASCII.GetString(respBytesList.ToArray()));

                // Send message to the server:
                Console.Write("You: ");
                server.Send(Encoding.ASCII.GetBytes(Console.ReadLine()));
                Console.WriteLine();
            }
            catch (Exception ex) {
                Console.WriteLine("Error: " + ex.Message);
                return;
            }
        }

    }

    static void Main(string[] args) {

        IPEndPoint serverEp = new IPEndPoint(IPAddress.Parse("192.168.1.2"), 2222);

        Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        server.ReceiveTimeout = -1;

        // Connect to the server.
        try { server.Connect(serverEp); }
        catch (Exception) {
            Console.WriteLine("Establish connection with server (" + serverEp + ") failed!");
            Console.ReadKey();
            return;
        }

        Console.WriteLine("Connection with server (" + serverEp + ") established!");
        WorkWithServer(server);

        Console.WriteLine("Press any key for exit...");
        Console.ReadKey();
    }

根据需要进行编辑。