Socket - Java客户端,C#服务器

6
我正在制作一款由两部分组成的程序。
第一部分:在电脑上运行的C#服务器套接字应用程序,监听命令并相应地执行。
第二部分:在手机上运行的Java客户端套接字应用程序,在按下按钮时向计算机发送指令。
目前,我可以从客户端向服务器发送命令,并且一切都很好。但我的问题是:当我向服务器发送特定命令时,我希望服务器回复客户端并让客户端读取该回复。
问题在于,当客户端尝试阅读时,它会超时。
Java客户端程序:
class ClientThread implements Runnable 
{   
    public void run() 
    {
        try 
        {
            Socket socket = new Socket(serverIpAddress, serverPort);
            socket.setSoTimeout(5000);

            while (true) 
            {
                try 
                {
                    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
                    Log.d("Nicklas", "Out it goes");
                    out.println(Command);

                    if (Command == "CMD:GetOptions<EOF>")
                    {
                        Log.d("Nicklas", "Getting options");
                        try
                        {
                            Log.d("Nicklas", "Line 1");
                            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                            Log.d("Nicklas", "Line 2");
                            String answer = in.readLine();
                            Log.d("Nicklas", "answer = " + answer );
                        }
                        catch (Exception ee)
                        {
                            Log.d("Nicklasasasas", ee.toString());
                        }
                    }
                    break;

                } 

                catch (Exception e) 
                {
                    Log.d("Nicklas", "CAE = " + e.toString());
                    break;

                } 
            }
            socket.close();
        } 
        catch (ConnectException ee)
        {
            Log.d("Nicklas", "Kunne ikke forbinde");

        }
        catch (Exception e) 
        {
            Log.d("Nicklasssssss", e.toString());
        }
    }
}

这个函数被以下方式调用:

Thread cThread = new Thread(new ClientThread());
        cThread.start();

该程序使用全局变量"Command",具体信息取决于按下的按钮。

程序在"String answer = in.readline();"这一行失败,出现异常情况"java.net.SocketTimeoutException"。

以下是该程序的C#服务器部分:

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

        while (true)
        {
            //blocks until a client has connected to the server
            TcpClient client = this.tcpListener.AcceptTcpClient();

            //create a thread to handle communication
            //with connected client
            Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
            clientThread.Start(client);
        }
    }

    private void HandleClientComm(object client)
    {
        TcpClient tcpClient = (TcpClient)client;
        NetworkStream clientStream = tcpClient.GetStream();

        byte[] message = new byte[4096];
        int bytesRead;

        while (true)
        {
            bytesRead = 0;

            try
            {
                //blocks until a client sends a message
                bytesRead = clientStream.Read(message, 0, 4096);
            }
            catch
            {
                //a socket error has occured
                break;
            }

            if (bytesRead == 0)
            {
                //the client has disconnected from the server
                break;
            }

            //message has successfully been received
            ASCIIEncoding encoder = new ASCIIEncoding();
            //System.Diagnostics.Debug.WriteLine(encoder.GetString(message, 0, bytesRead));
            string Input = (encoder.GetString(message, 0, bytesRead));
            Input = Input.Trim();
            object[] obj = new object[1];
            obj[0] = Input;
            if (Input == "CMD:GetOptions<EOF>")
            {
                try
                {
                    byte[] buffer = encoder.GetBytes("CMD:Accepted");
                    clientStream.Write(buffer, 0, buffer.Length);
                    clientStream.Flush();
                    MessageBox.Show("Client program asked for reply");
                }
                catch (Exception e)
                {
                    MessageBox.Show("Oh it no work!: " + e.ToString());
                }
            }
            else
            {
                Udfor(Input);
            }


        }

        tcpClient.Close();
    }

在Form1()中使用以下内容:

this.tcpListener = new TcpListener(IPAddress.Any, 4532);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();

C#服务器似乎工作正常,并显示消息框“客户端程序请求回复”。有人能发现错误吗?

你的问题是客户端似乎没有从服务器接收到响应吗?在给定的超时时间内(例如5秒),如果套接字没有接收到响应,则抛出 SocketTimeoutException 异常。你确定服务器正在发送响应吗? - D-Dᴙum
嗯,我不是100%确定,但有99%的把握。C#程序: 如果(输入 ==“CMD:GetOptions<EOF>”) { byte[] buffer = encoder.GetBytes("CMD:已接受"); clientStream.Write(buffer,0,buffer.Length); clientStream.Flush(); MessageBox.Show("哦,它想要选项"); }这会在接收到消息后运行。最后还显示了messageBox,所以我非常确定它确实发送了回复。 - user1285334
1个回答

1
我找到问题所在了!问题出在C#上。当服务器发送回“CMD:Accepted”命令时,它从未关闭套接字,因此Android应用程序无法确定何时完成读取!在刷新后立即关闭套接字+当我已经关闭它时不再关闭它,就解决了问题!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接