简体   繁体   中英

Android TCP send data trough one socket

Having the following code:

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);
}

I'm calling the register method once, at the application's start. Ever after I'm using the send method to send data to the server. The problem is that only the first send called from register is properly received from the server. All the others are being sent, but not received(Or if they are, i don't see them being displayed). My server code:

 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);
     }
  }

Ok, but when i try this code from the client, it works by sending a little bit more traffic(I don't want that).

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();

I need a little explanation on this one.
From one socket can you have multiple OutPutStreams?
Why am i getting socketClosed exception when i close an OutPutStream, and try to open a new one on the same socket. I am defining outToServer only in send now:

    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();
}

You need to set TCP_NODELAY on the socket. The default is for data to be buffered until it will fill an entire packet. When the buffer is full, a packet is sent. However, for this protocol you want the data to be sent immediately so that the server can respond.

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

From one socket can you have multiple OutputStreams?

The socket only has one input stream and one output stream.

Why am i getting socketClosed exception when i close an OutputStream, and try to open a new one on the same socket.

Because closing a socket input or output stream closes the socket, as it says in the Javadoc.

NB The server code you posted never closes anything. The client code you posted never closes anything and only sends one message.

NB 2 PrintWriter swallows exceptions and should not be used over the network. Use BufferedWriter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM