简体   繁体   English

管理多个/多个tcp连接

[英]Manage several/multiple tcp connections

I have a server application and client application with the functionality already working. 我有一个服务器应用程序和客户端应用程序,功能已经工作。 Let me show you how I connect my client application to my server app: 让我告诉你如何将我的客户端应用程序连接到我的服务器应用程序:

                              //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..
                       ....

ok now on the client side lets say I want to establish a connection then send some data through the stream 好吧现在在客户端可以说我想建立连接然后通过流发送一些数据

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

since I am able to send bytes I am able to send files or everything that I want. 因为我能够发送字节,我能够发送文件或我想要的一切。 the technique that I use is that if I send the string file for example to the server then the server will start listening for a file. 我使用的技术是,如果我将字符串文件发送到服务器,那么服务器将开始侦听文件。 It will open a stream and write the received bytes to that file. 它将打开一个流并将接收到的字节写入该文件。 If a different keyword is send the server will start listening on a different method etc.. 如果发送了不同的关键字,服务器将开始监听不同的方法等。

So when dealing with one server and one client everything works great. 因此,当处理一个服务器和一个客户端时,一切都很好。 Now I want to add more clients and need them to also connect to the server. 现在我想添加更多客户端,并且还需要它们连接到服务器。 I know that several connections can be establish on the same port just like we do it with por 80 on websites... I do not know how to manage several connections. 我知道可以在同一个端口上建立多个连接,就像我们在网站上使用por 80一样...我不知道如何管理多个连接。 so one thing I was thinking was to leave everything as it is. 所以我想的一件事就是把一切都保留下来。 if a connection is established then tell the server to start another thread listening for other connections on the same port. 如果建立了连接,则告诉服务器启动另一个线程,侦听同一端口上的其他连接。 with this technique I will have several threads running plus I just know the basics of multrythreading. 使用这种技术,我将运行多个线程,而且我只知道多线程的基础知识。 If this technique is my best option I will start implementing it. 如果这种技术是我最好的选择,我将开始实施它。 You guys out there are really knowledgeable about all this so it will be nice if someone can point me on the right direction. 你们这些人真的对这一切都了如指掌,所以如果有人可以指出我正确的方向,那就太好了。 Or maybe I should listen on several ports. 或许我应该听几个端口。 if the server is already connected on port 7777 for example then do not accept connections from that port and start listening on port 7778 for example. 例如,如果服务器已在端口7777上连接,则不接受来自该端口的连接并开始侦听端口7778。 I mean there could be so many different ways of achieving what I need and you guys probably know the best way. 我的意思是可能有很多不同的方式来实现我需要的东西,你们可能知道最好的方法。 I just know the basics of networking... 我只知道网络的基础知识......

You could implement a class that encapsulates TCP behavior. 您可以实现一个封装TCP行为的类。 Check this class: 检查这个课程:

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
        }
    }

}

You could use this in your code: 您可以在代码中使用它:

                        //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..
                       ....
}

You could use threading: 你可以使用线程:

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

The target method would look like this 目标方法看起来像这样

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

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

If you are not familiar with multithreading, it is important you learn at least the basics first. 如果您不熟悉多线程,那么首先要了解至少基础知识非常重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM