我可以使用两个不同的线程来读取和写入同一个套接字,而不需要在java中进行任何同步吗?
我的代码是 -
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();
}
}
}
两个问题 -
Write构造函数中的字符串将打印在客户端终端上。为什么会这样?
为什么在Write run()方法中抛出异常?
答案 0 :(得分:2)
我可以使用两个不同的线程来读取和写入同一个套接字,而不需要在java中进行任何同步吗?
您无法避免同步,因为Socket的实现已经同步。
如果只有一个线程读取和另一个线程写入,则可以避免其他同步。
Write构造函数中的字符串将打印在客户端终端上。为什么会这样?
最有可能的原因是您也在客户端上运行该代码。
为什么在Write run()方法中抛出异常?
您有错误,如果您阅读它并告诉我们它是什么(包括堆栈跟踪)会更容易诊断
注意:线程需要一些时间来启动和运行。如果立即关闭连接,线程可能甚至没有机会在关闭连接之前读取连接。
read.start();
write.start();
incomming.close(); // == kill the connection
而不是使用
while(!done ...) {
if (condition)
done = true;
}
您可以使用
while(...) {
if (condition)
break;
}