[英]The server is not receiving the message of the client
我是Java套接字編程的新手,正在嘗試編寫一個應在2個單獨的控制器上運行的程序。 我編寫了一個用作通信類的線程。
我定義了一個名為SFlag的標志,以便在程序中的任何位置將此標志的值更改為1時,相應的控制器都會通過sendPackets()函數向另一個控制器發送問候消息。 另一個控制器將通過ReceivePackets類接收此消息,並將打印結果。 這是代碼:
// My UDP communication class
public class MainConn implements Runnable {
// Sockets, 1 for sending, and one for receiving
DatagramSocket socket1, socket2;
// localIP
private InetAddress localIP;
private InetAddress leaderIP;
// classes to run on separate Threads
private ReceivePackets rcvThread;
@Override
public void run() {
process();
}
public void process() {
// initialize some parameters
init1();
// Make Thread for receiving packets and update counters from all
// controller
rcvThread = new ReceivePackets();
Thread r = new Thread(rcvThread);
r.start();
sendPackets();
}
public void init1() {
try {
// create sockets
String tempString = config.get("localPort");
localPort = Integer.parseInt(tempString);
logger.info("----------here is==========" +localPort);
leaderIP = InetAddress.getByName("127.0.0.1");
logger.info("----------here is==========" +leaderIP);
socket1 = new DatagramSocket(localPort); // for sending
socket2 = new DatagramSocket(localPort + 1); // for receiving
} catch (SocketException | UnknownHostException e) {
e.printStackTrace();
}
}
//*******************************************************
public void sendPackets() {
// will be used to begin sending message type II after 3*hello
// period
while (true) {
try {
// if network not converged, send message type I, contains:
// type number (1) then
if (SFlag == 1) {
logger.info("Sending the message");
String tempString = new String("Hello");
byte[] data = tempString.getBytes();
DatagramPacket sentPacket = new DatagramPacket(data, tempString.length());
sentPacket.setAddress(leaderIP);
sentPacket.setPort(20222);
socket1.send(sentPacket);
SFlag = 0;
}
else {
logger.info("Nothinggggggggggggg");
}
Thread.sleep(5000);// wait for Hello period
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch(Exception e){
e.printStackTrace();
}
}
}
class ReceivePackets implements Runnable {
@Override
public void run() {
try {
while (true) {
logger.info("---------------waiting------------------");
byte[] data = new byte[1000];
DatagramPacket receivedPacket = new DatagramPacket(data, data.length);
socket2.receive(receivedPacket);
String senderIP = receivedPacket.getAddress().getHostAddress();
String senderPort = "" + receivedPacket.getPort();
String message = new String(data, 0, receivedPacket.getLength());
logger.info(message);
System.out.println("Received Message: "+message);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
當SFlag的值更改為1時,似乎第一個控制器正在發送消息(已打印“正在發送消息”),但是在第二個控制器上接收消息似乎存在問題,因為已接收到消息不打印。
問題是什么?
您的代碼存在一些問題:
(1)由於兩個線程都依賴SFlag
進行通信,因此請確保使用volatile
關鍵字聲明它:
private volatile int SFlag = 0;
volatile
關鍵字可防止對該變量進行緩存,因此兩個線程始終會看到相同的值。 除此之外,對volatile
變量的讀寫操作是原子的。
(2)您在此行中有一個硬編碼的端口號:
sentPacket.setPort(20222);
確保這是ReceivePackets
線程使用的端口號。 理想情況下,我們永遠不要將魔術數字與代碼混在一起。 因此,您應該將該端口號移至單獨的變量或常量。
(3)在Java中,您不應該使用new
創建一個String
。 例如,這是一種不好的做法:
String tempString = new String("Hello"); // bad practice
你應該做:
String tempString = "Hello";
我的最后一條建議是:清理代碼 。 您可以在此處查看有關發送和接收數據報包的Oracle教程: https : //docs.oracle.com/javase/tutorial/networking/datagrams/clientServer.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.