【问题标题】:Sending binary data multiple times using Sockets in Java/Android在 Java/Android 中使用套接字多次发送二进制数据
【发布时间】:2015-05-24 14:30:18
【问题描述】:

我需要在 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 编程,我使用 Scalaid,这是多次发送二进制数据的代码。 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()

【问题讨论】:

    标签: java android python scala sockets


    【解决方案1】:

    从这个帖子: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);
    

    【讨论】:

      猜你喜欢
      • 2017-03-05
      • 2013-08-21
      • 2012-08-23
      • 2011-05-31
      • 2020-06-26
      • 2011-04-21
      • 1970-01-01
      • 2011-08-11
      • 2012-10-11
      相关资源
      最近更新 更多