好吧,爲了好玩我現在在Java中練習多線程和網絡,但我遇到了一些非常奇怪的事情。我有我的代碼結構如下。客戶端和服務器是線程,其中包含PacketListener,這些線程也是在接收到數據包時將數據包添加到ConcurrentLinkedQueue的線程。Java多線程,奇怪的東西
我的服務器類看起來像這樣
public Server(int port) {
setThreadName("ServerThread");
this.clients = new ArrayList<SocketAddress>();
try {
//this.socket = new DatagramSocket(null);
//this.socket.setReuseAddress(true);
//this.socket.bind(new InetSocketAddress(port));
//this.socket.setReuseAddress(true);
//this.socket.bind(new InetSocketAddress(port));
//sender = new PacketSender(socket);
this.listener = new PacketListener(port);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
listener.start();
}
synchronized private void processPacket(DatagramPacket packet) {
if (packet != null) {
String data = new String(packet.getData(), 0, packet.getLength());
System.out.println("Received a packet " + data);
if (data.equalsIgnoreCase("connecting")) {
System.out.println("wut");
} else {
System.out.println("Packet from :" + packet.getAddress().toString() + " saying: " + data);
}
} else {
System.out.println("Packet == null");
}
}
@Override
public void run() {
System.out.println("running server on port " + socket.getLocalPort());
while (isRunning()) {
if (listener.hasPacket()) {
System.out.println("listener has a packet");
processPacket(listener.getNextPacket());
}
sleep(1); // sleep for 1ms (keeps cpu usage from sky rocketing)
}
}
我PacketListener類看起來像這樣
public PacketListener(int port) throws IOException {
this.socket = new DatagramSocket(null);
this.socket.setReuseAddress(true);
this.socket.bind(new InetSocketAddress(port));
System.out.println("Packet listener bound @ " + socket.getLocalAddress() + " on port " + socket.getLocalPort());
receivedPackets = new ConcurrentLinkedQueue<DatagramPacket>();
}
synchronized private void addPacket(DatagramPacket packet) {
if (!receivedPackets.add(packet)) {
System.err.println("We dropped a packet because full queue");
} else {
System.out.println("We added a received packet! - " + receivedPackets.size());
}
}
synchronized public boolean hasPacket() {
return !receivedPackets.isEmpty();
}
synchronized public DatagramPacket getNextPacket() {
return receivedPackets.poll();
}
@Override
public void run() {
byte[] buffer = new byte[256];
DatagramPacket inPacket = new DatagramPacket(buffer, buffer.length);
while (isRunning()) {
try {
socket.receive(inPacket);
addPacket(inPacket);
} catch (Exception e) {
e.printStackTrace();
}
}
}
現在奇怪的是,在客戶端,說我送了幾包。 比方說,我發送「你好」,然後在「測試1」,然後「測試2」 服務器將打印出
Packet received
We added a received packet! - 1
listener has a packet
Packet received
Received a packet test1
We added a received packet! - 1
Packet from :/127.0.0.1 saying: test1
listener has a packet
Packet received
Received a packet test2
We added a received packet! - 1
Packet from :/127.0.0.1 saying: test2
listener has a packet
這實際上應該打印出來沿
We added a received packet! - 1
listener has a packet
Received a packet hello
Packet from :/127.0.0.1 saying: hello
We added a received packet! - 1
listener has a packet
Received a packet test1
Packet from :/127.0.0.1 saying: test1
We added a received packet! - 1
listener has a packet
Received a packet test2
Packet from :/127.0.0.1 saying: test2
有什麼奇怪的?你期望看到什麼? – markspace 2014-09-02 23:21:20
它打印出來的一切嗎?你真的發送全部3個數據包,「你好」,「test1」和「test2」嗎?你的輸出是有意義的*如果你發送「test1」*第一個*,並且如果在打印數據包內容之後,你的監聽器將打印「test2」等。 – 2014-09-02 23:22:28
我有客戶端設置,以便我輸入字符串並將它們發送到服務器,這是服務器正在接收和打印的內容。我也有客戶在發送之前通過照片驗證包數據。應該說,像 我們增加了接收數據包 - 1個 聽者從/127.0.0.1包 收到一個數據包你好 包說:你好 等所有三個 – grundyboy34 2014-09-02 23:27:22