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 の場合に呼び出されるメソッドを THIS PART にしたいと考えています。どのように私はそれを行うだろう. 前もって感謝します :)

ところで、すべてのクライアント要求は新しい 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 に答える