Java多线程套接字 - 如何按顺序发送响应

Java多线程套接字 - 如何按顺序发送响应

问题描述:

对不起,我看到的问题的漫长描述。Java多线程套接字 - 如何按顺序发送响应

我有下面的代码记录,我一直在尝试使它使用线程顺序发送消息。我继续在客户端上获取以下控制台输出。

呼应客户端消息:您好:0 14210577 14210579

呼应客户端消息:您好:1 14211379 14211379

呼应客户端消息:您好:2 14212181 14212181

呼应客户端消息:你好:3 14212981 14212982

呼应客户留言:您好:4 14213782 14213782

呼应客户端消息:您好:5 14214582 14214583

呼应客户端消息:您好:6 14215383 14215383

呼应客户端消息:您好:7 14216184 14216184

呼应客户端消息:您好:8 14216984 14216984

呼应客户端消息:您好:9 14217785 14217785

在CLIEN控制台输出我要找实现t是像下面

呼应客户端消息(其中消息2之后的所有消息消息2之前发送):您好:0 14210577 14210579

呼应客户端消息:您好: 1 14211379 14211379

呼应客户端消息:您好:3 14212981 14212982

呼应客户端消息:您好:4 14213782 14213782

ECH卷板机客户端消息:您好:5 14214582 14214583

呼应客户端消息:您好:6 14215383 14215383

呼应客户端消息:您好:7 14216184 14216184

呼应客户端消息:您好:8 14216984 14216984

呼应客户端消息:您好:9 14217785 14217785

呼应客户端消息:您好:2 14212181 14217885

客户端上的控制台输出具有以下内容;并且我可以看到服务器对消息3的响应在消息2完成其等待时间之前不会被发送。我希望服务器在消息2完成等待之前发送其对消息3的响应。

传入客户端消息:您好:2 15430652

调用ServerThread发送消息:15430653

从发送消息中返回ServerThread:15430653

在sendMessage.doWork()

:15430653

sendMessage.doWork()完成等待:15430753

传入客户端消息:您好:3 15430753

如何让线程继续处理其他消息而无需等待消息2完成等待?

在此先感谢您的任何意见。

服务器类:

// Built off the following tutorials 
// https://www.youtube.com/watch?v=2cQJJwoSNLk 
// https://www.youtube.com/watch?v=nCIw0h1C8Qo 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.util.concurrent.TimeUnit; 

public class Server{ 

    public static void main(String[] args) { 
     try { 
      new Server().runServer(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public void runServer() throws IOException{ 
     final int PORT = 4444; 
     ServerSocket serverSocket = new ServerSocket(PORT); 
     System.out.println(new StringBuilder().append("Server up and ready for connections...").toString()); 
     while(true){ 
      Socket socket = serverSocket.accept(); 
      new Thread(new ServerThread(socket)).start(); 
     } 
    } 

    public class ServerThread implements Runnable{ 

     private Socket socket; 
     private String message; 

     ServerThread(Socket socket){ 
      this.socket = socket; 
     } 

     public void run(){ 

      try { 
       this.message = null; 
       PrintWriter printWriter = new PrintWriter(socket.getOutputStream(),true); 
       BufferedReader bufferedReader = new BufferedReader(new InputStreamReader (socket.getInputStream())); 
       while((message = bufferedReader.readLine()) != null){ 
        System.out.println(new StringBuilder().append("incoming client message: ").append(message).toString()); 
        long sendTime = System.nanoTime(); 
        if(message.trim().startsWith("Hello: 2")){ 
         sendTime = System.nanoTime() + 100000000; 
        } 

        System.out.println(new StringBuilder().append("calling Send Message in ServerThread: ").append(" ").append(TimeUnit.NANOSECONDS.toMillis(System.nanoTime())).toString()); 

        new Thread( 
          new SendMessage(printWriter, 
              sendTime, 
              new StringBuilder().append("echoing client message: ").append(message).append(" ").append(TimeUnit.NANOSECONDS.toMillis(System.nanoTime())).toString() 
              ) 
          ).start(); 

        System.out.println(new StringBuilder().append("returned from Send Message in ServerThread: ").append(" ").append(TimeUnit.NANOSECONDS.toMillis(System.nanoTime())).toString()); 
       } 
      } catch (IOException e) { 
      } 

     } 

    } 

} 

客户端类:

// Built off the following tutorials 

// https://www.youtube.com/watch?v=2cQJJwoSNLk 

// https://www.youtube.com/watch?v=nCIw0h1C8Qo 



import java.io.BufferedReader; 

import java.io.IOException; 

import java.io.InputStreamReader; 

import java.io.PrintWriter; 

import java.net.Socket; 

import java.net.UnknownHostException; 

import java.util.concurrent.TimeUnit; 


public class Client { 

public static final int PORT = 4444; 

public static void main(String[] args) throws UnknownHostException, IOException { 

    Socket socket = new Socket("localhost",PORT); 
    PrintWriter printWriter = new PrintWriter(socket.getOutputStream(),true); 
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
    for(int x = 0; x<10;x++){ 
     if(x==5){ 
      printWriter.println(new StringBuilder().append("Hello: ").append(x).append(" ").append(TimeUnit.NANOSECONDS.toMillis(System.nanoTime())).toString()); 
     }else{ 
      printWriter.println(new StringBuilder().append("Hello: ").append(x).append(" ").append(TimeUnit.NANOSECONDS.toMillis(System.nanoTime())).toString()); 
     } 
     System.out.println(new StringBuilder().append(bufferedReader.readLine())); 
    } 
    //socket.close(); 
} 


} 

SendMessage函数类:

import java.io.PrintWriter; 
import java.util.concurrent.TimeUnit; 

public class SendMessage implements Runnable{ 

private PrintWriter printWriter; 
private Long SendTimeInNanos; 
private String message; 

public SendMessage(PrintWriter printWriter, Long SendTimeInNanos, String message){ 
    this.printWriter = printWriter; 
    this.SendTimeInNanos = SendTimeInNanos; 
    this.message = message; 
} 

@Override 
public void run() { 
    doWork(); 
} 

private void doWork(){ 
    System.out.println(new StringBuilder().append("in sendMessage.doWork(): ").append(" ").append(TimeUnit.NANOSECONDS.toMillis(System.nanoTime())).toString()); 
    //sleep until the appropriate time 
    while(this.SendTimeInNanos > System.nanoTime()){ 
     try { 
      //sleep until appropriate time 
      Thread.sleep(TimeUnit.NANOSECONDS.toMillis(this.SendTimeInNanos-System.nanoTime())); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

    System.out.println(new StringBuilder().append("sendMessage.doWork() done waiting: ").append(" ").append(TimeUnit.NANOSECONDS.toMillis(System.nanoTime())).toString()); 

    //send at appropriate time 
    this.printWriter.println(new StringBuilder().append(this.message).toString()); 
} 

} 
+0

如果您想要特定的序列,为什么要使用线程? – EJP

+0

我不想要一个特定的序列,但我想模拟丢弃和延迟的数据包......丢弃的数据包很容易模拟......只是不发送它们......延迟的数据包似乎是一个问题模拟。 – merkman

总体代码看起来确定。这个问题可能是你创建的方式,开始你的主题:

while(true){ 
     Socket socket = serverSocket.accept(); 
     new Thread(new ServerThread(socket)).start(); 
    } 

看起来像每一个新的线程创建一个新的前相当快完成其执行。要实现异步线程执行,请尝试创建若干个ServerThread实例并一次启动所有实例:

while(true){ 
     Socket socket = serverSocket.accept(); 
     List<Thread> threads = new ArrayList<>(); 
     for (int i = 0; i < 4; i++) 
     { 
      threads.add(new Thread(new ServerThread(socket))); 
     } 
     threads.forEach(Thread::start); 
} 
+0

所以....你是说每个客户端消息应该有自己的服务器线程? – merkman