Problem sending data over UDP sockets
This is kind of a followup to the question I had yesterday. I had a homework assignment to send and receive data with a client/server TCP socket connection. I would like to make a version of it using UDP. The idea is that I can redirect standard I/O and send the streams using UDP. For example, if I type in:
server: java UDPServer 5555 < file1.txt
client: java UDPClient localhost 5555 > file2.txt
It should send the data in file1.txt from the server to client's file2.txt. When I run the client/server pair in separate terminals, file2.txt is created but the data is never actually sent. Instead it seems like I am stuck in an infinite loop, where I cannot enter anything into the terminal unless I kill the application.
The server code is:
public static final int BUF_SIZE = 256;
public static void main(String[] args) throws IOException{
port = Integer.parseInt(args[0]);
DatagramSocket serverSocket = new DatagramSocket(port);
BufferedInputStream input = new BufferedInputStream(System.in);
BufferedOutputStream output = new BufferedOutputStream(System.out);
byte[] receiveData = new byte[BUF_SIZE];
byte[] sendData = new byte[BUF_SIZE];
byte[] buf = new byte[BUF_SIZE];
String sentence;
if(System.in.available() > 0) {
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
InetAddress address = receivePacket.getAddress();
int bytesRead = 0;
while((bytesRead = input.read(buf, 0, BUF_SIZE)) != -1) {
sentence = new String(buf, 0, bytesRead);
sendData = sentence.getBytes();
DatagramPac开发者_开发问答ket sendPacket = new DatagramPacket(sendData, sendData.length, address, port);
serverSocket.send(sendPacket);
}
} else {
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
sentence = new String(receivePacket.getData());
output.write(sentence.getBytes());
}
serverSocket.close();
input.close();
output.close();
}
And the client code is:
public static final int BUF_SIZE = 256;
public static void main(String[] args) throws IOException{
String hostName = args[0];
port = Integer.parseInt(args[1]);
DatagramSocket clientSocket = new DatagramSocket();
InetAddress address = InetAddress.getByName(hostName);
BufferedInputStream input = new BufferedInputStream(System.in);
BufferedOutputStream output = new BufferedOutputStream(System.out);
byte[] sendData = new byte[BUF_SIZE];
byte[] receiveData = new byte[BUF_SIZE];
byte[] buf = new byte[BUF_SIZE];
String sentence;
if(System.in.available() > 0) {
int bytesRead = 0;
while((bytesRead = input.read(buf, 0, BUF_SIZE)) != -1) {
sentence = new String(buf, 0, bytesRead);
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, address, port);
clientSocket.send(sendPacket);
}
} else {
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
sentence = new String(receivePacket.getData());
output.write(sentence.getBytes());
}
clientSocket.close();
input.close();
output.close();
}
I am still new to socket programming so I am basing this off of example code in my textbook. Is there some glaring mistake that I am making that is preventing the data from being transferred? Thanks very much for your patience and help!
The first problem you have is that client.main doesn't run because your shell command is wrong. For some reason, with Java you can't redirect output how it's traditionally done. You can simply put a few print statements at the beginning of client.main to see nothing executes. Try this:
java UDPClient localhost 5555 | tee file2.txt
See redirect Java output.
The other problem you have is that both the client and server are waiting to receive a datagram. You have in the server code:
if(System.in.available() > 0) {
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
And you have in the client code:
else {
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
sentence = new String(receivePacket.getData());
output.write(sentence.getBytes());
}
Note that the else statement will always execute because System.in.available will always return 0. Remember your not redirecting input to the client, so there's nothing in System.in. To fix this you need to first send a client datagram so that the server can respond with the contents of file2.txt.
You're missing all the things you need to do to make this work. Where's the code to do transmit pacing, retransmissions, acknowledgements, reordering, and so on? If you want to use UDP, you have to do yourself all the things TCP does for you.
See, for example RFC 1350 for an example of a file transfer protocol layered on top of UDP.
精彩评论