java - 在Java/Android中使用套接字多次发送二进制数据

标签 java android python scala sockets

我需要在Android设备上使用Java套接字多次发送二进制数据。
这是一个简单的对象,可导出run()和send()方法。

public class GpcSocket {

    private Socket socket;

    private static final int SERVERPORT = 9999;
    private static final String SERVER_IP = "10.0.1.4";

    public void run() {
        new Thread(new ClientThread()).start();
    }

    public int send(byte[] str) {
        try {
            final BufferedOutputStream outStream = new BufferedOutputStream(socket.getOutputStream());
            outStream.write(str);
            outStream.flush();
            outStream.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return str.length;
    }

    class ClientThread implements Runnable {
        @Override
        public void run() {
            try {
                InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
                socket = new Socket(serverAddr, SERVERPORT);
            } catch (UnknownHostException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }
}

对于Android编程,我使用Scaloid,这是多次发送二进制数据的代码。 count由参数给出。 result是Byte [Array]类型的数据,并且gpconCreate()方法中初始化为gpc = new GpcSocket()
gpc.run()
for (i <- 1 to count) {
  val length = gpc.send(result)
  toast(s"Sent: $i $length")
}

问题是,即使我尝试多次发送数据,接收方也只能接收到一个数据包。这是我发送信息5次时在服务器(接收方)端显示的内容:
55:2015-03-21 03:46:51 86: <RECEIVED DATA>
10.0.1.27 wrote:
56:2015-03-21 03:46:51 0:
10.0.1.27 wrote:
57:2015-03-21 03:46:51 0:
10.0.1.27 wrote:
58:2015-03-21 03:46:51 0:
10.0.1.27 wrote:
59:2015-03-21 03:46:51 0:

我的问题是
  • 这是为什么?为什么接收器只接收一次?发件人表明已发送信息五次。
  • 是否需要在发送多次之前只使用一次run()?或者,每当我使用send()时都必须调用run()吗?

  • 这是Python中的服务器端代码:
    import SocketServer
    from time import gmtime, strftime
    
    count = 1
    
    class MyTCPHandler(SocketServer.BaseRequestHandler):
        """
        The RequestHandler class for our server.
    
        It is instantiated once per connection to the server, and must
        override the handle() method to implement communication to the
        client.
        """
    
        def handle(self):
            # self.request is the TCP socket connected to the client
            self.data = self.request.recv(1024).strip()
            print "{} wrote:".format(self.client_address[0])
            global count
            count += 1
            print "%d:%s %d:%s" % (count, strftime("%Y-%m-%d %H:%M:%S", gmtime()), len(self.data), self.data)
            # just send back the same data, but upper-cased
            self.request.sendall(self.data.upper())
    
    if __name__ == "__main__":
        HOST, PORT = "10.0.1.4", 9999
    
        # Create the server, binding to localhost on port 9999
        server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
    
        # Activate the server; this will keep running until you
        # interrupt the program with Ctrl-C
        server.serve_forever()
    

    最佳答案

    从这篇文章:Sending ByteArray using Java Sockets (Android programming)How to fix java.net.SocketException: Broken pipe?,似乎send()方法是错误的。

    使用完资源后,请关闭它们

    我将send()修改为创建套接字并在使用完毕后将其关闭的方法很简单。

    public int send(byte[] str) throws IOException {
        InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
        socket = new Socket(serverAddr, SERVERPORT);
        out = socket.getOutputStream();
        out.write(str);
        out.flush();
        out.close();
        socket.close();
        return str.length;
    }
    

    修改调用者代码

    调用它的scala代码被修改为调用send()方法。
    // gpc.run()
    for (i <- 1 to count) {
      ...
      val length = gpc.send(result)
      println(s"Sent: $i $length")
    }
    
    ... in initializer
    gpc = new GpcSocket()
    

    在Android中更改政策模式

    提示:android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145),应为Android设备添加此代码,以防止E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: scaloid.example, PID: 1791 android.os.NetworkOnMainThreadException错误。
    val policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
    

    关于java - 在Java/Android中使用套接字多次发送二进制数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29179100/

    相关文章:

    android - 获取 wifi 连接是否被锁定(密码保护)

    android - 如何在操作栏中显示 EditText 时聚焦并显示软键盘?

    Java - 对话框如何显示在关闭时的同一位置?

    java - 如何区分 textField.setText() 和在 java 中手动向 textField 添加文本?

    java - Spring Integration Gateway 服务方法在启动/停止时不返回

    android - 控制 Firebase 断开连接超时

    python - 如何让 pandas 将 xlsx 文件(包括其工作表)复制到新的 xlsx 文件中

    python - GPU计算能力3.0,但最低要求的Cuda能力为3.5

    python - Jupyter notebook 中的 !ls (Python 3)

    java - 如何重构scala代码?