管理多个/多个tcp连接

时间:2011-08-29 16:17:58

标签: c# networking tcp

我有一个服务器应用程序和客户端应用程序,其功能已经运行。让我向您展示如何将我的客户端应用程序连接到我的服务器应用程序:

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

因为我能够发送字节,所以我能够发送文件或我想要的所有内容。我使用的技术是,如果我将字符串文件发送到服务器,那么服务器将开始侦听文件。它将打开一个流并将接收到的字节写入该文件。如果发送了不同的关键字,服务器将开始监听不同的方法等。

因此,当处理一个服务器和一个客户端时,一切都很好。现在我想添加更多客户端,并且还需要它们连接到服务器。我知道可以在同一个端口上建立多个连接,就像我们在网站上使用por 80一样...我不知道如何管理多个连接。所以我想的一件事就是把一切都保留下来。如果建立了连接,则告诉服务器启动另一个线程,侦听同一端口上的其他连接。使用这种技术,我将运行多个线程,而且我只知道多线程的基础知识。如果这种技术是我最好的选择,我将开始实施它。你们这些人真的对这一切都了如指掌,所以如果有人可以指出我正确的方向,那就太好了。或许我应该听几个端口。例如,如果服务器已在端口7777上连接,则不接受来自该端口的连接并开始侦听端口7778。我的意思是可能有很多不同的方式来实现我需要的东西,你们可能知道最好的方法。我只知道网络的基础......

2 个答案:

答案 0 :(得分:1)

您可以使用线程:

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
}

如果您不熟悉多线程,那么首先要了解至少基础知识非常重要。

答案 1 :(得分:1)

您可以实现一个封装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..
                       ....
}