0

我正在编写一个线程 tcp 服务器,在这个线程中我写了这个:

private void HandleClientComm(object client)
    {
        TcpClient tcpClient = (TcpClient)client;
        NetworkStream clientStream = tcpClient.GetStream();
        byte[] message = new byte[4096];
        int bytesRead;
        byte[] buffer = null;
        string answer = null;

        while (true)
        {
            bytesRead = 0;

            try
            {
                bytesRead = clientStream.Read(message, 0, 4096);
            }
            catch(Exception ex)
            {   

                write("Error: " + ex.Message);

                break;
            }

            if (bytesRead == 0)
            {
                write("Client connection lost!");
                break;
            }

            txtLogger.Text += "Command accepted\n";
            ASCIIEncoding encoder = new ASCIIEncoding();

            clientreq = encoder.GetString(message, 0, bytesRead);
            clientreq = clientreq.ToUpper();

            if (clientreq == "CLIENTIP")
            {
                //THIS PART
                answer = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address.ToString();
                buffer = encoder.GetBytes(answer);
            }
//some more if's
clientStream.Write(buffer, 0, buffer.Length);
            clientStream.Flush();
            write("Server finished work.");
            }
//some more code

现在我希望这部分是一个方法,如果输入是 CLIENTIP,则按照客户端的要求调用该方法。我会怎么做。提前致谢 :)

顺便说一句,每个客户端请求都应该使用新的 tcp 连接来处理。我已经尝试过了,结果很糟糕:客户端冻结并且发生了 NOTRespondin

public void IPKLIENTI()
    {
        TcpClient client = this.TCPMonitoruesi.AcceptTcpClient();
        TcpClient tcpClient = (TcpClient)client;
        NetworkStream clientStream = tcpClient.GetStream();
        byte[] Bufer = null;
        string answer = null;
        ASCIIEncoding encoder = new ASCIIEncoding();


        answer = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address.ToString();
        Bufer = encoder.GetBytes(answer);

    }
4

1 回答 1

0

To break up your if statement to handle the "CLIENTIP" request, you need to pass the TcpClient you are connected to to the method which does all the work (the IPKLIENTI method) as below.

if (clientreq == "CLIENTIP")
{
    // call to IPCLIENTI retrives the RemoteEndPoint of the given TcpClient and encodes a response to be sent
    buffer = IPKLIENTI(client, encoder);
}

A revised IPKLIENTI implementation is shown below. The key changes are:

  • Takes a TcpClient as a paramater rather than accepting a new TcpClient (this behavior lets you work with the TcpClient you recieved the request from and will later respond to, the old behavior attempted to accept another client all together)

  • Takes an ASCIIEncoding object to do the encoding with - you could re-build it as you used to, but this is tidier and ensures consistency in the future

  • We don't need to access the NetStream in this function, so we can do away with the call to GetStream

  • We return an encoded byte array to use as the response to the client when we call clientStream.Write() later in the HandleClientComm function

Revised IPKLIENTI method:

// Method takes a TcpClient Object and Encoder, returning a response to the CLIENTIP request
public byte[] IPKLIENTI(TcpClient tcpClient, ASCIIEncoding encoder)
{
    string answer = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address.ToString();
    byte[] buffer = encoder.GetBytes(answer);
    return buffer;
}

Essentially it just stores the intended response in a string (the RemoteEndPoint of the given TcpClient) and then encodes it via the given encoder, returning a byte array of the encoded response to be sent to the client.

于 2013-04-29T17:34:25.770 回答