简体   繁体   English

通过Java中的套接字进行全双工通信

[英]Full duplex communication through socket in java

Can I use two different threads to read and write from the same socket without any synchronization in java? 我可以使用两个不同的线程从同一套接字读取和写入,而无需在Java中进行任何同步吗?

My code is - 我的代码是-

public class Server {

    public static void main(String[] args) {
        Serve s = new Serve();
    }
}
class Serve {

ServerSocket sS;
String serverAddress;
int port;

public Serve() {
    serverAddress = "127.0.0.1";
    port = 8091;
    try  {
        sS = new ServerSocket(port);
        System.out.println("Server listening on port " + port+ " ...");
        Socket incomming = sS.accept();
        System.out.println("Connected to Client.");
        Runnable r = new Read(incomming);
        Runnable w = new Write(incomming);
        Thread read = new Thread(r);
        Thread write = new Thread(w);
        read.start();
        write.start();
        incomming.close();
        sS.close();
    }
    catch(IOException e) {
        e.printStackTrace();    
    }
}
}
class Read implements Runnable {

Socket readSocket;

public Read(Socket readSocket) {
    this.readSocket = readSocket;
}

@Override
public void run() {
    try {
        InputStream inStream = readSocket.getInputStream();
        try (Scanner in = new Scanner(inStream)) {
            boolean done = false;
            PrintWriter out = new PrintWriter(System.out, true);
            while(!done && in.hasNextLine()) {
                String line = in.nextLine();
                out.println("Client>" + line);
                if(line.trim().equals("BYE")) done = true;
            }
        }
    }
    catch(Exception e) {
        e.printStackTrace();
    }


}

}

class Write implements Runnable {

Socket writeSocket;

public Write(Socket writeSocket) {
    this.writeSocket = writeSocket;
    System.out.println("This is printed on the client terminal");
}

@Override
public void run() {
    try {
        OutputStream outStream = writeSocket.getOutputStream();
        try (Scanner in = new Scanner(System.in)) {
            boolean done = false;
            PrintWriter out = new PrintWriter(outStream, true);
            while(!done && in.hasNextLine()) {
                System.out.print("Server>");
                String line = in.nextLine();
                out.println(line);
                if(line.trim().equals("BYE")) done = true;
            }
         }
    }
    catch(Exception e) {
        System.out.println("Exception thrown here");
        e.printStackTrace();
    }


}

}

Two Problems - 两个问题-

  1. The string in the Write constructor is getting printed on the client terminal. Write构造函数中的字符串正在客户端上打印。 Why is this happening? 为什么会这样呢?

  2. Why is the exception being thrown in the Write run() method? 为什么在Write run()方法中引发异常?

Can I use two different threads to read and write from the same socket without any synchronization in java? 我可以使用两个不同的线程从同一套接字读取和写入,而无需在Java中进行任何同步吗?

You can't avoid synchronization because the implementation for Socket is already synchronized. 您无法避免同步,因为Socket的实现已经同步。

You can avoid additional synchronization if you only have one thread reading and another thread writing. 如果只有一个线程读而另一个线程写,则可以避免其他同步。

The string in the Write constructor is getting printed on the client terminal. Write构造函数中的字符串正在客户端上打印。 Why is this happening? 为什么会这样呢?

Most likely because you are running that code on the client as well. 最可能的原因是您也在客户端上运行了该代码。

Why is the exception being thrown in the Write run() method? 为什么在Write run()方法中引发异常?

You have an error, which would be easier to diagnose if you read it and told us what it was (including the stack trace) 您有一个错误,如果您阅读并告诉我们它是什么(包括堆栈跟踪),将会更容易诊断

Note: Threads take time to start and run. 注意:线程需要花费一些时间来启动和运行。 If you close the connection immediately, the threads might not even get a chance to read the connection before you have closed it. 如果立即关闭连接,则在关闭连接之前,线程可能甚至没有机会读取连接。

    read.start();
    write.start();
    incomming.close(); // == kill the connection

Instead of using 而不是使用

 while(!done ...) {

    if (condition)
        done = true;
 }

You can use 您可以使用

 while(...) {

    if (condition)
       break;
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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