Управление несколькими / несколькими TCP-соединениями - PullRequest
0 голосов
/ 29 августа 2011

У меня есть серверное приложение и клиентское приложение с уже работающим функционалом. Позвольте мне показать вам, как я подключаю свое клиентское приложение к своему серверному приложению:

                              //SERVER
           //  instantiate variables such as tempIp, port etc...
           //  ...
           // ...    

            server = new TcpListener(tempIp, port); //tempIp is the ip address of the server.

            // Start listening for client requests.
            server.Start();

            // Buffer for reading data
            Byte[] bytes = new Byte[MaxChunkSize];
            String data = null;


            // Enter the listening loop.
            while (disconect == false)
            {
                Console.Write("Waiting for a connection... ");

                // Perform a blocking call to accept requests.
                // You could also user server.AcceptSocket() here.
                client = server.AcceptTcpClient(); // wait until a client get's connected...
                Console.WriteLine("Connected!");

                // Get a stream object for reading and writing
                stream = client.GetStream();

                // now that the connection is established start listening though data
               // sent through the stream..
                int i;
                try
                {
                    // Loop to receive all the data sent by the client.
                    while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
                    {

                        // Translate data bytes to a ASCII string.
                        data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
                        Console.WriteLine("Received: {0}", data);
                       // etc..
                       ....

Хорошо, теперь на стороне клиента, скажем, я хочу установить соединение, а затем отправить некоторые данные через поток

                           //Client
            client = new TcpClient(serverIP, port);

            // Get a client stream for reading and writing.
            stream = client.GetStream();

            //then if I wish to send the string hello world to the server I would do:
            sendString(stream, "Hello world");


     protected void sendString(NetworkStream stream, string str)
    {
        sendBytes(stream, textToBytes(str));
    }

    protected void sendBytes(NetworkStream stream, Byte[] data)
    {
        // Send the message to the connected TcpServer. 
        stream.Write(data, 0, data.Length);
    }
    protected static Byte[] textToBytes(string text)
    {
        return System.Text.Encoding.ASCII.GetBytes(text);
    }

так как я могу отправлять байты, я могу отправлять файлы или все, что я хочу. Техника, которую я использую, заключается в том, что если я отправлю строковый файл, например, на сервер, то сервер начнет прослушивать файл. Он откроет поток и запишет полученные байты в этот файл. Если отправлено другое ключевое слово, сервер начнет прослушивание другим методом и т. Д.

Так что при работе с одним сервером и одним клиентом все работает отлично. Теперь я хочу добавить больше клиентов и мне нужно, чтобы они также подключались к серверу. Я знаю, что несколько соединений могут быть установлены на один и тот же порт, как мы делаем это с портом 80 на веб-сайтах ... Я не знаю, как управлять несколькими соединениями поэтому я думал о том, чтобы оставить все как есть. если соединение установлено, то скажите серверу запустить другой поток, прослушивающий другие соединения на том же порту. с помощью этой техники у меня будет запущено несколько потоков, и я просто знаю основы многопоточности. Если этот метод - мой лучший вариант, я начну его применять. Вы, ребята, действительно хорошо осведомлены обо всем этом, поэтому было бы хорошо, если бы кто-то указал мне верное направление. Или, может быть, я должен слушать несколько портов. например, если сервер уже подключен к порту 7777, не принимайте подключения с этого порта и, например, начните прослушивать порт 7778. Я имею в виду, что может быть так много разных способов достижения того, что мне нужно, и вы, ребята, наверняка знаете лучший способ. Я просто знаю основы работы в сети ...

Ответы [ 2 ]

1 голос
/ 04 июня 2013

Вы можете реализовать класс, который инкапсулирует поведение TCP.Проверьте этот класс:

public class SimpleListener
{
    private System.Net.Sockets.TcpListener _tcpListen;
    //declare delegate to handle new connections
    public delegate void _new_client(System.Net.Sockets.TcpClient tcpclient);

    //declare a clients container (or something like...). OPTION 1
    List<System.Net.Sockets.TcpClient> _connected_clients;

    //declare an event and event handler (the same for _new_client) for new connections OPTION 2
    public event _new_client new_tcp_client;



    //public (The list of connected clients).
    public List<System.Net.Sockets.TcpClient> ConnectedClients { get { return _connected_clients; } }


    public SimpleListener(string ip, int listenport)
    {
        System.Net.IPAddress ipAd = System.Net.IPAddress.Parse(ip);
        _tcpListen = new System.Net.Sockets.TcpListener(new System.Net.IPEndPoint(ipAd,listenport));
        _connected_clients = new List<System.Net.Sockets.TcpClient>();
    }

    //Fire this method to start listening...
    public void Listen()
    {
        _tcpListen.Start();
        _set_listen();
    }
    //... and this method to stop listener and release resources on listener
    public void Stop()
    {
        _tcpListen.Stop();
    }

    //This method set the socket on listening mode... 
    private void _set_listen()
    {
        //Let's do it asynchronously - Set the method callback, with the same definition as delegate _new_client
        _tcpListen.BeginAcceptTcpClient(new AsyncCallback(_on_new_client), null);
    }



    //This is the callback for new clients
    private void _on_new_client(IAsyncResult _async_client)
    {
        try
        {
            //Lets get the new client...
            System.Net.Sockets.TcpClient _tcp_cl = _tcpListen.EndAcceptTcpClient(_async_client);
            //Push the new client to the list
            _connected_clients.Add(_tcp_cl);
           //OPTION 2 : Fire new_tcp_client Event - Suscribers will do some stuff...
            if (new_tcp_client != null) 
            {
                new_tcp_client(_tcp_cl);
            }
            //Set socket on listening mode again... (and wait for new connections, while we can manage the new client connection)
            _set_listen();
        }
        catch (Exception ex)
        {
           //Do something...or not
        }
    }

}

Вы можете использовать это в своем коде:

                        //SERVER
       //  instantiate variables such as tempIp, port etc...
       //  ...
       // ...    

        SimpleListener server = new SimpleListener(tempIp, port); //tempIp is the ip address of the server.
        //add handler for new client connections
        server.new_tcp_client += server_new_tcp_client;
        // Start listening for client requests.
        server.Listen();
        .... //No need to loop. The new connection is handled on server_new_tcp_client method



    void server_new_tcp_client(System.Net.Sockets.TcpClient tcpclient)
{
     // Buffer for reading data
            Byte[] bytes = new Byte[MaxChunkSize];
            String data = null;
            Console.WriteLine("Connected!");

                // Get a stream object for reading and writing
            System.IO.Stream stream = tcpclient.GetStream();

               // now that the connection is established start listening though data
               // sent through the stream..
                int i;
                try
                {
                    // Loop to receive all the data sent by the client.
                    while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
                    {

                        // Translate data bytes to a ASCII string.
                        data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
                        Console.WriteLine("Received: {0}", data);
                       // etc..
                       ....
}
1 голос
/ 29 августа 2011

Вы можете использовать потоки:

var client = server.AcceptTcpClient();
var t = new Thread(new ParameterizedThreadStart(AccentClient));
t.Start(client);

Целевой метод будет выглядеть так

public void AccentClient(object clientObj)
{
    var client = clientObj as TcpClient;

    // Do whatever you need to do with the client
}

Если вы не знакомы с многопоточностью, важно, чтобы вы сначала изучили хотя бы основы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...