java TCP客户端: howto send data while reading

标签 java sockets tcp

这是我使用套接字连接的第一个 java 步骤。我喜欢编写一个 TCP 客户端来连接到服务器并读取服务器将发送的所有数据。来自服务器的每条消息都将以 0x00 结束。

第一个问题: 我怎样才能读取这个可变的消息长度?

第二个问题: 如果用户通过键盘输入文本,则该文本应在我接收时发送到服务器。但是当我从服务器读取数据时如何发送数据呢?

这是我到目前为止的代码:

import java.io.*;

 public class Client {
     public static void main(String[] args) {
    Client client = new Client();
    try {
        client.test();
    } catch (IOException e) {
        e.printStackTrace();
    }
     }
     void test() throws IOException {
    String ip = "127.0.0.1"; // localhost
    int port = 12345;
    java.net.Socket socket = new java.net.Socket(ip,port); // verbindet sich mit Server
    String zuSendendeNachricht = "Hello World0x00";
    schreibeNachricht(socket, zuSendendeNachricht);
    while (true){
        String empfangeneNachricht = leseNachricht(socket);
        System.out.println(empfangeneNachricht);
        }
     }
     void schreibeNachricht(java.net.Socket socket, String nachricht) throws IOException {
     PrintWriter printWriter =
        new PrintWriter(
        new OutputStreamWriter(
            socket.getOutputStream()));
    printWriter.print(nachricht);
    printWriter.flush();
    }
    String leseNachricht(java.net.Socket socket) throws IOException {
    BufferedReader bufferedReader =
        new BufferedReader(
        new InputStreamReader(
            socket.getInputStream()));
    char[] buffer = new char[200];
        int anzahlZeichen = bufferedReader.read(buffer, 0, 200); // blockiert bis Nachricht empfangen
        String nachricht = new String(buffer, 0, anzahlZeichen);
        System.out.println(nachricht);
    }
 }

如何读取可变消息长度

最佳答案

第一个问题:我如何读取这个可变消息长度?

只需读取大小为 1 字节的传入数据并检查 0x00 上的每个字节。

第二个问题:如果用户通过键盘输入文本,则该文本应该在我接收时发送到服务器。但是当我从服务器读取数据时如何发送数据呢?

启动两个独立的线程。一种用于阅读,一种用于写作。 伪代码:

Thread readingThread = new Thread(new Runnable() {
  @Override
  public void run() {
    //do reading here...
  }
});
readingThread.start();

Thread writingThread = new Thread(new Runnable() {
  @Override
  public void run() {
    //do writing here...
  }
});
writingThread.start();

在下面找到一个读取每个字节并检查 0x00 的工作示例。这里没有使用线程。

Client.java内容:

package tcpserverclient;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Client {

    private static final Logger LOG = Logger.getLogger(Client.class.getName());

    private String getData(InputStream stream2server) {
        BufferedInputStream inputStream = new BufferedInputStream(stream2server);

        StringBuilder incomingData = new StringBuilder("");
        try {
            int c;
            LOG.info("reading incoming data...");
            while ((c = inputStream.read()) != -1) {
                if (c == 0) {
                    break;
                } else {
                    incomingData.append((char) c);
                    System.out.print((char) c);
                }
            }
            LOG.info("\ndata complete.");
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        return incomingData.toString();
    }

    private void startListen(int port) {
        try {
            ServerSocket serverSocket = new ServerSocket(port);
            while (true) {
                LOG.info("\nListening on port " + port);
                Socket socket = serverSocket.accept();
                LOG.info("incoming call...");

                InputStream incoming = socket.getInputStream();
                OutputStream outgoing = socket.getOutputStream();
                String data = getData(incoming);
                LOG.info(data);

                outgoing.close();
                incoming.close();
                socket.close();
            }

        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new Client().startListen(9999);
    }
}

Server.java的内容:

package tcpserverclient;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class Server {

    public void sendCommand(String ip, int port, String cmd) {
        try {
            Socket socket = new Socket(ip, port);
            InputStream fromServer = socket.getInputStream();
            OutputStream toServer = socket.getOutputStream();
            socket.setSoTimeout(0);

            byte[] ba = cmd.getBytes();
            byte[] ba0 = new byte[ba.length + 1];
            System.arraycopy(ba, 0, ba0, 0, ba.length);
            ba0[ba.length] = 0;

            toServer.write(ba0);

            fromServer.close();
            toServer.close();
            socket.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new Server().sendCommand("127.0.0.1", 9999, "Hal, can you read me?");
    }
}

首先启动Client.java,然后启动Server.java。输出是这样的:

run:
Jan 06, 2015 9:19:42 AM tcpserverclient.Client startListen
Information: 
Listening on port 9999
Jan 06, 2015 9:19:44 AM tcpserverclient.Client startListen
Information: incoming call...
Jan 06, 2015 9:19:44 AM tcpserverclient.Client getData
Information: reading incoming data...
Jan 06, 2015 9:19:44 AM tcpserverclient.Client getData
Information: 
data complete.
Jan 06, 2015 9:19:44 AM tcpserverclient.Client startListen
Information: Hal, can you read me?
Jan 06, 2015 9:19:44 AM tcpserverclient.Client startListen
Information: 
Listening on port 9999
Hal, can you read me?

关于java TCP客户端: howto send data while reading,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27789014/

相关文章:

java - 从 XSD 问题生成 JAXB 类

java - itext在梳字段java中空间出数字

c - 尝试接受套接字连接,检索并处理消息,然后将此消息写入终端

c - 接受无效参数失败,后跟错误的文件描述符

linux - 确定 TCP 负载事件/统计数据

c++ - 将加密层添加到我的 TCP 客户端/服务器应用程序的最直接方法是什么?

java - 在 Java 代码中设置 JRuby 属性

java - 从字节转换为字符串的任何其他逻辑

Python Django Errno 54 'Connection reset by peer'

java - 从java中的套接字断开连接