2
假设发送消息的顺序为 1,2,3
a. 采用无连接 socket 的到达顺序有 3!不同排列:(1,2,3)(1,3,2)(2,1,3)(2,3,1)(3,1,2)(3,2,1)
b. 采用面向连接 socket 的到达顺序只有 1 种:(1,2,3)
4
// instantiates a datagram socket for sending the data
DatagramSocket mySocket = new DatagramSocket();
byte[] buffer = new byte[100];
DatagramPacket
datagram =
new DatagramPacket(buffer,
buffer.length,
receiverHost,
receiverPort);
mySocket.setSoTimeout(5000); // set timeout to 5 seconds
try {
mySocket.receive(datagram);
}
catch (SocketTimeoutException ex) {
System.out.println("time out on receive");
}
6
a.
b.
按顺序执行的结果如下:
双方都收到对方发出的消息。
但是如果调换了顺序,则运行结果如下:
双方都进入了阻塞状态,原因在于 Example2SenderReceiver 执行 send 操作后便紧接着
执行 receive 操作进入阻塞状态,此时 Example2ReceiverSender 还没有执行 receive 操作,所
以发送到的信息丢失了,而当运行 Example2ReceiverSender 时由于执行了 receive 操作但是
没有收到信息,所以它也进入了阻塞状态。
所以执行顺序非常重要。
c.
修改后的程序名称是:Example22ReceiverSender 和 Example22SenderReceiver
运行结果是两个进程相互通信,不断发送消息:
原因分析:
Example22ReceiverSender 运行后执行 receive 先进入阻塞,然后 Example22SenderReceiver
运行后执行 send 发送消息 msg2 并执行 receive 进入阻塞,Example22ReceiverSender 继
续运行并且发送 msg1 并且执行 sleep(3000),Example22SenderReceiver 接受 msg1 后继
续运行并且执行 sleep(3000)。
两者循环执行便出现上面的结果。
下面为修改后的源代码:
Example22ReceiverSender
import java.net.*;
import java.lang.Thread.*;
/**
* This example illustrates a process which sends then receives
* using a datagram socket.
* @author M. L. Liu
*/
public class Example22ReceiverSender {
// An application which sends then receives a message using
// connectionless datagram socket.
// Four command line arguments are expected, in order:
//
//
//
//
public static void main(String[] args) {
if (args.length != 4) {
System.out.println("This program requires four command line arguments");
} else {
try {
InetAddress receiverHost = InetAddress.getByName(args[0]);
int receiverPort = Integer.parseInt(args[1]);
int myPort = Integer.parseInt(args[2]);
String message = args[3];
MyDatagramSocket mySocket = new MyDatagramSocket(myPort);
// instantiates a datagram socket for both sending
// and receiving data
// First wait to receive a datagram from the socket
try {
while (1 > 0) {
System.out.println(mySocket.receiveMessage());
// Now send a message to the other process.
mySocket.sendMessage(receiverHost, receiverPort, message);
//wait(1000);
Thread.sleep(3000);
}
} catch (Exception ex) {
mySocket.close();
}
} // end try
catch (Exception ex) {
ex.printStackTrace();
} //end catch
} //end else
} //end main
} //end class
Example22SenderReceiver
import java.net.*;
import java.lang.Thread.*;
/**
* This example illustrates a process which sends then receives
* using a datagram socket.
* @author M. L. Liu
*/
public class Example22SenderReceiver {
// An application which sends then receives a message using
// connectionless datagram socket.
// Four command line arguments are expected, in order:
//
//
//
//
public static void main(String[] args) {
if (args.length != 4) {
System.out.println("This program requires four command line arguments");
} else {
try {
InetAddress receiverHost = InetAddress.getByName(args[0]);
int receiverPort = Integer.parseInt(args[1]);
int myPort = Integer.parseInt(args[2]);
String message = args[3];
MyDatagramSocket mySocket = new MyDatagramSocket(myPort);
// instantiates a datagram socket for both sending
// and receiving data
try {
while (true) {
mySocket.sendMessage(receiverHost, receiverPort, message);
// now wait to receive a datagram from the socket
System.out.println(mySocket.receiveMessage());
}
} catch (Exception ex) {
mySocket.close();
}
} // end try
catch (Exception ex) {
ex.printStackTrace();
} //end catch
} //end else
} //end main
} //end class