[英]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.