recently I am attempting an exercise that requires to design a server with TWO clients based on tcp socket. After connected, the SenderClient should send a message typed by user to Server, and Server should then forward that message to the ReceiverClient. It is like:
SenderClient -> Server -> ReceiverClient
Only when user types "quit" in sender, all the programs will be terminated, otherwise they are always listening for messages.
Now I have met the problem that: when I run that three programs in Eclipse Luna, what I found is that the message can be successfully passed from SenderClient -> Server -> ReceiverClient for only one time. And after that, the message will be blocked at the Server. Can you guys also run those three programs on your computer to see the strange phenomenon. Thank you and really need help here.
import java.io.*;
import java.net.*;
public class Server {
public static void main (String args[]) {
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
OutputStream os = null;
PrintWriter pw = null;
String info = null;
try {
// listening to port
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("Server is listening to port 8888...");
while (true) {
// respond to clients
Socket receiverSocket = serverSocket.accept();
System.out.println("receiver client connected!");
Socket senderSocket = serverSocket.accept();
System.out.println("sender client connected!");
// get input stream, read messages from sender
is = senderSocket.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
info = br.readLine();
// close all resources when user types "quit"
if (info.equalsIgnoreCase("quit")) {
// close resources when user types "quit"
is.close();
isr.close();
br.close();
os.close();
pw.close();
serverSocket.close();
System.out.println("Server terminated!");
break;
}
// print out the message
if (info != null) {
System.out.println("Sender -> Server: " + info);
}
// get output stream, forward messages to receiver
os = receiverSocket.getOutputStream();
pw = new PrintWriter(os);
pw.println(info);
pw.flush();
} // end while
} catch (IOException e) {
e.printStackTrace();
} // end try...catch
} // end main method
} // end class Server
import java.io.*;
import java.net.*;
public class ReceiverClient {
public static void main (String args[]) {
InputStream is = null;
BufferedReader br = null;
String info = null;
try {
while (true) {
// create receiver socket with host and port number
Socket receiverSocket = new Socket("localhost", 8888);
// get input stream, read the information
is = receiverSocket.getInputStream();
br = new BufferedReader(new InputStreamReader(is));
info = br.readLine();
// close all resources when user types "quit"
if (info.equalsIgnoreCase("quit")) {
is.close();
br.close();
System.out.println("Receiver client terminated!");
break;
}
// print out the message
if (info != null) {
System.out.println("Sender -> Server -> Receiver: " + info);
}
receiverSocket.close();
} // end while
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} // end try...catch
} // end main method
} // end class ReceiverClient
import java.io.*;
import java.net.*;
public class SenderClient {
public static void main (String args[]) {
OutputStream os = null;
PrintWriter pw = null;
BufferedReader br = null;
String userInput = null;
try {
while (true) {
// create sender socket with host and port number
Socket senderSocket = new Socket("localhost", 8888);
// get message from user input
System.out.println("Please input a message:");
br = new BufferedReader(new InputStreamReader(System.in));
userInput = br.readLine();
// get output stream, send message to server
os = senderSocket.getOutputStream();
pw = new PrintWriter(os);
pw.println(userInput);
pw.flush();
senderSocket.close();
// close all resources when user types "quit"
if (userInput.equalsIgnoreCase("quit")) {
os.close();
pw.close();
System.out.println("Sender client terminated!");
break;
}
} // end while
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} // end try...catch
} // end main method
} // end class SenderClient
Socket receiverSocket = serverSocket.accept();
The accept()
method of ServerSocket
is a blocking operation: it waits for an incoming connection and until then the thread this code runs on waits. The first time the loop is executed correctly because you have the two clients connect to the server. The second time the loop gets executed you wait for another incoming client. A solution for this is to handling of the messages in a separate thread by implementing the java.lang.Runnable
interface, which is the code that runs on the newly launched thread:
class ClientConnection implements Runnable{
private Socket sender;
private Socket receiver;
public ClientConnection(Socket sender, Socket receiver){
this.sender = sender;
this.receiver = receiver;
}
@Override
public void run(){
is = sender.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
OutputStream os = receiver.getOutputStream();
PrintWriter pw = new PrintWriter(os);
boolean clientQuit = false;
while(!clientQuit){
info = br.readLine();
if (info.equalsIgnoreCase("quit")) {
// close resources when user types "quit"
is.close();
isr.close();
br.close();
os.close();
pw.close();
serverSocket.close();
System.out.println("Server terminated!");
clientQuit = true;
} else{
pw.println(info);
pw.flush;
}
}
}
}
Whenever the server gets two incoming connections, it fires up a new Thread
that will handle the connection and then continues on accepting new incoming connections:
while (true) {
// respond to clients
Socket receiverSocket = serverSocket.accept();
System.out.println("receiver client connected!");
Socket senderSocket = serverSocket.accept();
System.out.println("sender client connected!");
ClientConnection connection = new ClientConnection(senderSocket, receiverSocket);
Thread connectionThread = new Thread(connection);
connectionThread.start();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.