且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

C# - 连接客户端 - 服务器系统中的客户端

更新时间:2022-10-25 09:12:22

只需一个便条:



 尝试 
{
// 任何
// ...
}
catch (例外e) // 不要
{ // DO
throw ; // SUCH
} // 事情!





完全等同于拥有逻辑上,这个片段中没有异常处理,但它只是浪费资源。在这个片段中没有异常处理将是***的选择。如果你打算以这种方式写下你剩下的代码,其余部分对我没有兴趣:我不会为你的项目下注一分钱。



此外,这个想法是什么:每个客户的线程(抱歉,我想确认)?这可能是一个坏主意,不可扩展。线程数不应该取决于客户端数量。



关于客户端到客户端的问题没有多大意义。让我们这样说吧:忘记客户端 - 服务器模型,它太有限了。与其他一些部分的关系,应用程序的任何部分都可以同时扮演服务器和客户端的角色。但是,TCP通道是不对称的,它建立连接的条件:一方是监听器并接受连接,另一方连接。建立连接后,根据您可以设计的某些应用程序级协议,这两个部分都可以读取和写入套接字。从这一点开始。我不想给你进一步的推荐,因为我不知道你有什么样的沟通方式。



- SA

I have a multithreaded server-client system where clients chat with the server and receive the sent message back, but only client-to-server way of communication. I want to make it client-to-client. The thing is that I don''t know how to distinguish between the clients and perhaps attach each-other''s network streams to one-another.

I don''t want to make it for 2 clients only, but to make it in a generic way so I can connect i.e. 6 clients, so that every second connected client finds the previous connected one.

I have thought of a TcpClient[] array where I store the clients objects after their connection is accepted, but then I just can''t figure out how to distinguish between them and attach them to one-another.

Here is the code of the server class:

class TheServer
{
    private TcpListener tcpListener;
    private Thread threadListener;
    TheMessage msg;
    public TcpClient[] clientList = new TcpClient[100];
    private int n = 0;

    public void StartServer()
    {
        try
        {
            this.tcpListener = new TcpListener(IPAddress.Any, 8000);
            this.threadListener = new Thread(new ThreadStart(ListenForClients));
            this.threadListener.Start();

            Console.WriteLine("Local end point: " + tcpListener.LocalEndpoint);
        }
        catch (Exception e)
        {
            throw;
        }
    }

    private void ListenForClients()
    {
        this.tcpListener.Start();

        while(true)
        {
            // block until a client has connected to the server
            TcpClient client = this.tcpListener.AcceptTcpClient();
            if (n == 0)
            {
                clientList[0] = client;
            }
            else
            {
                n++;
                clientList[n] = client;
            }

            // create thread to handle communication with connected client
            Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
            clientThread.Start(clientList[n]);

        }
    }

    private void HandleClientComm(object client)
    {
        TcpClient tcpClient = (TcpClient)client;
        NetworkStream stm = tcpClient.GetStream();
        msg = new TheMessage();

        while (true)
        {
            Byte[] bSize = new Byte[sizeof(Int32)];
            stm.Read(bSize, 0, bSize.Length);

            Byte[] bData = new Byte[BitConverter.ToInt32(bSize, 0)];
            stm.Read(bData, 0, bData.Length);

            msg = XmlRefactorServer.ByteArrayToObject<TheMessage>(bData);
            String str = msg.Message;
            Console.WriteLine(str);
            stm.Flush();

            // send back to client
            msg.Message = str;
            Byte[] bDataBack = XmlRefactorServer.ObjectToByteArray<TheMessage>(msg);

            // NetworkStream stm2 = ------> perhaps here should get the second client stream ?!

            Byte[] bSizeBack = BitConverter.GetBytes(bDataBack.Length);

            stm2.Write(bSizeBack, 0, bSizeBack.Length);
            stm2.Write(bDataBack, 0, bDataBack.Length);
            stm2.Flush();

        }

        tcpClient.Close();

    }

Just one note:

try
{
    // anything
    // ...
}
catch (Exception e) //   DON'T
{                   //   DO
    throw;          //   SUCH
}                   //   THINGS!



is strictly equivalent to having no exception handling in this fragment, logically, but it just wastes resources. Not having exception handling in this fragment would be the best option. If you are going to write the rest of you code in such a manner, the rest of it presents no interest to me: I would not bet a cent for your project.

Besides, what''s the idea: a thread per client (sorry for asking, I want to make sure)? This would be a bad idea, not scalable. The number of threads should not depend on the number of clients.

The question on "client to client" does not make much sense. Let''s put it this way: forget client-server model, it''s too limiting. Any part of the application can play the role of a server and a client at the same time, in relations to some other parts. However, a TCP channel is asymmetric, it terms of establishing of a connection: one side is a listener and accepts a connection, another part connects. When a connection is established, both parts can read and write to a socket, according to some application-level protocol you can devise. Start from this point. I don''t want to give you further recommendation, because I don''t know what kind of communication scenario do you have in mind.

—SA