對不起,我看到的問題的漫長描述。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());
}
}
如果您想要特定的序列,爲什麼要使用線程? – EJP
我不想要一個特定的序列,但我想模擬丟棄和延遲的數據包......丟棄的數據包很容易模擬......只是不發送它們......延遲的數據包似乎是一個問題模擬。 – merkman