安卓套接字异常 "socket is closed"

6
当我尝试运行一个由回声服务器和Android客户端组成的测试,使用以下代码时,我总是会收到异常消息“socket is closed”。这段代码可以简单地向服务器发送消息,并从服务器接收消息,但如果您想同时执行这两个操作,它就无法正常工作…我非常好奇为什么会出现这种问题,如果我想要先向回声服务器发送消息,然后再接收消息,应该如何修复它?
            // Server IP address 
            InetAddress serverIp;

            // try to connect Server
            try {

                // set up server IP address
                serverIp = InetAddress.getByName("192.168.17.1");

                // set up port
                int serverPort=12345;

                // initiate socket connection
                Socket clientSocket=new Socket(serverIp,serverPort);

                BufferedOutputStream out = new BufferedOutputStream(clientSocket.getOutputStream());
                out.write("Send From Android1111, stitch ".getBytes());
                out.flush();

                //wait to receive Server's msg 
                BufferedReader  br =new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 

                total.toString();*/
            // Display received msg with Toast
                Toast.makeText(getApplicationContext(), br.readLine(), Toast.LENGTH_SHORT ).show();

            //close connection
                clientSocket.close();             

//              out.close();
//              out = null;
            } catch (IOException e) {
                // display exception with Toast
                Toast.makeText(getApplicationContext(),e.toString(), Toast.LENGTH_SHORT).show();
            }

很遗憾,它仍然无法工作...我按照你的指示进行了修改,代码如下:
            // set up Server IP address 
            serverIp = InetAddress.getByName("192.168.2.2");

            // set up Server port
            int serverPort=12345;

            // initiate socket connection
            Socket clientSocket=new Socket(serverIp,serverPort);

                // open input and output stream
            OutputStream out = clientSocket.getOutputStream();
            InputStream in = clientSocket.getInputStream();

            //send msg
            out.write("Send From Android1111, bitch ".getBytes());


                // receive msg from server
            byte[] buffer = new byte[in.available()];
            in.read(buffer);
            String rMsg = new String(buffer);
            Toast.makeText(getApplicationContext(), rMsg, Toast.LENGTH_LONG ).show();

            //close input and output stream
            in.close();
            out.close();

             //關閉連線
       clientSocket.close(); 
        } catch (IOException e) {
            // 出錯後顯示錯誤訊息Toast
            Toast.makeText(getApplicationContext(),e.toString(), Toast.LENGTH_SHORT).show();
        }

为了方便助手理解,这是服务器部分的Python代码:

# Practice Echo Server Program written in Python
import socket

# host = '' means it binds to any available interface
host = ''
port = 12345

# socket() function returns a socket object whose methods implement the various socket system calls.
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

# Bind the socket to address. 
s.bind((host,port))

# Listen for connections made to the socket. The backlog argument specifies 
# the maximum number of queued connections and should be at least 0; 
# the maximum value is system-dependent (usually 5), the minimum value is forced to 0.
s.listen(5)

# Accept a connection. The socket must be bound to an address and listening for 
# connections. The return value is a pair (conn, address) where conn is a new socket 
# object usable to send and receive data on the connection, and address is the address
# bound to the socket on the other end of the connection.
conn, addr = s.accept()
print 'Connected by', addr

# Receive data from the socket. The return value is a string representing the data received.
# The maximum amount of data to be received at once is specified by bufsize. See the Unix
# manual page recv(2) for the meaning of the optional argument flags; it defaults to zero.
# Note For best match with hardware and network realities, the value of bufsize should be 
# a relatively small power of 2, for example, 4096.

while 1:
    data = conn.recv(1024)
    if not data: break 
    print 'received data is : ', repr(data)
    conn.send(data)

conn.close()

3
请尽量不要在此处发布“冒犯性”的言论。谢谢。我已为您修正。 - prolink007
3个回答

6
我猜您是按错误的顺序做了正确的事情。也许服务器太快了,当您尝试读取响应时,它已经被接收并消失了。
按照教程从Socket中读取和写入中提供的规则:
  1. 打开一个socket
  2. 打开一个输入流和输出流到socket。
  3. 根据服务器的协议从流中读取和写入。
  4. 关闭流。
  5. 关闭socket。
您看到区别了吗?首先打开输入和输出流,然后开始发送请求。
我相信如果您遵循这个顺序,它会起作用的。

不行...对我还是不起作用...太奇怪了...这次只有toast显示空字符串...奇怪... - shanwu
1
@user1145976请不要将代码作为答案发布。只需更新您的问题即可。关于您正在使用的代码,_in.available()_仅在某些情况下有效。因此,请不要使用它。只需使用我提供的示例代码,其中包含一个BufferedReader和_readLine()_函数。 - Robert

0

我曾经遇到过类似的问题,通过编辑gradle.properties文件以允许代理连接而解决了它。我按照Nadeem Shaik在https://github.com/facebook/react-native/issues/2726中的解释添加了上述行。

systemProp.http.proxyHost=proxyHost
systemProp.http.proxyPort=proxyPort

systemProp.https.proxyHost=proxyHost
systemProp.https.proxyPort=proxyPort

-2

你的应用程序需要在AndroidManifest.xml中添加INTERNET权限

<uses-permission android:name="android.permission.INTERNET"/>

这不会引发“socket closed”异常。 - user207421

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