Android TCP通过一个套接字发送数据

时间:2015-11-16 16:51:54

标签: java android sockets tcp send

拥有以下代码:

public static PrintWriter outToServer;

private static Socket clientSocket;
    public static void register(InetAddress ip, int port, String name) {
    try {
        Utils.ip = ip;
        Utils.port = port;
        Utils.name = name;

        clientSocket = new Socket(Utils.ip, Utils.port);
        outToServer = new PrintWriter(clientSocket.getOutputStream(),true);

        send("reg:" + name);
}   catch (Exception e) {
        e.printStackTrace();
    }
 }
public static void send(String str) {
        outToServer.println(str);
}

我在应用程序启动时调用register方法一次。我使用send方法将数据发送到服务器之后。问题是只有从send调用的第一个register才能从服务器正确接收。所有其他人都被发送但未收到(或者如果他们是,我看不到他们被显示)。我的服务器代码:

 public static void main(String argv[]) throws Exception {
  String clientSentence;
 ServerSocket welcomeSocket = new ServerSocket(9876);
 while (true) {
  Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(
  new InputStreamReader(connectionSocket.getInputStream()));
clientSentence = inFromClient.readLine();
System.out.println("Received: " + clientSentence);
     }
  }

好的,但是当我从客户端尝试此代码时,它会通过发送更多流量(我不希望这样)来工作。

public static PrintWriter outToServer;

private static Socket clientSocket;
    public static void register(InetAddress ip, int port, String name) {
     try {
      Utils.ip = ip;
      Utils.port = port;
      Utils.name = name;

    send("reg:" + name);
}   catch (Exception e) {
    e.printStackTrace();
}
  }
  public static void send(final String str) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                clientSocket = new Socket(Utils.ip, Utils.port);
                outToServer = new PrintWriter(clientSocket.getOutputStream(), true);
                outToServer.println(str);
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    }).start();

我需要对此进行一些解释。
从一个插座可以有多个OutPutStream吗? 为什么我在关闭OutPutStream时遇到socketClosed异常,并尝试在同一个套接字上打开一个新的异常。我现在仅在outToServer中定义send

    public static void send(final String str) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                PrintWriter outToServer = new PrintWriter(clientSocket.getOutputStream(), true);
                outToServer.println(str);
                outToServer.close();
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    }).start();
}

2 个答案:

答案 0 :(得分:0)

您需要在套接字上设置TCP_NODELAY。默认情况下,数据将被缓冲,直到它将填满整个数据包。当缓冲区已满时,将发送数据包。但是,对于此协议,您希望立即发送数据,以便服务器可以响应。

https://stackoverflow.com/a/33658536/1172714

答案 1 :(得分:0)

  

从一个套接字可以有多个OutputStream吗?

套接字只有一个输入流和一个输出流。

  

为什么我在关闭OutputStream时遇到socketClosed异常,并尝试在同一个套接字上打开一个新的。

因为关闭套接字输入或输出流会关闭套接字,就像在Javadoc中所说的那样。

NB您发布的服务器代码从未关闭任何内容。您发布的客户端代码从不关闭任何内容,只发送一条消息。

NB 2 PrintWriter吞下异常,不应在网络上使用。使用BufferedWriter。