In the application that I inherited I was told that I had to convert the application from a one port one connection application to a multiple connection application. I'm still very new to socket programming and could really use some help in tackling this issue. Unfortunately, there are no other people on my team and I'm still trying to rifle through this code and learn the application.
Here is my code issue. I have a run() that calls a connect() in the same class but I have to be able to execute the rest of the run() code after EACH connection is made and verify that the activeSocket is still in the activeSockets list. Currently, the connect() code is setup to get ALL the connections in the maxActiveSockets list BEFORE moving on in the run() but again and that is part of the problem. I tried to break out of the outerloop after the first connection is made and then I do NOT see the second connection making it to the application. I could really use a second set of eyes on this.
I hope this makes sense.
Any help/direction would be appreciated. Thank you.
Here is the run() code:
public void run() {
int cnt;
Socket socket;
started = true;
if (!shouldTerminate) {
LOGGER.info("Connecting to host " + Thread.currentThread().getName());
connect();
hardstandin = false;
}
startTimers();
while (!shouldTerminate) {
// Make sure connection stays up unless shouldTerminate is set
if (!shouldTerminate) {
// ***** 20130912 MS - Per Shannon's email this method had to be changed to utilize the activeSocket fields. *****
Iterator<ActiveSocket> it = activeSockets.iterator();
while (it.hasNext()) {
ActiveSocket activeSocket = it.next();
socket = activeSocket.getSocket();
DataInputStream dataInputStream = activeSocket.getDataInputStream();
DataOutputStream dataOutputStream = activeSocket.getDataOutputStream();
// ORIGINAL CODE BLOCK STARTS HERE ==>
if (socket != null) {
synchronized (socket) {
try {
//LOGGER.info("Sending notifyAll on socket");
//socket.notifyAll();
if (!shouldTerminate) {
if (!getNeedReconnect().get()) {
hardstandin = false;
socket.wait();
}
}
} catch (final InterruptedException ex) {
LOGGER.info("Error waiting for new socket Interrupted Exception received.");
}
}
}
if (getNeedReconnect().get()) {
hardstandin = true;
final String channelName = "Bank " + bankInit + "; Bank ID " + getBankID();
final String logMessage = channelName.concat("\n\nData input stream on socket connection could not be read. Attempting to re-establish the connection.");
final String subject = channelName.concat(" Socket connection error");
ATMServer.sendNotification(subject, logMessage);
try {
socket.close();
} catch (final IOException ex) {
LOGGER.info(ERR_SOCKCLOSE);
}
socket = null;
try {
dataInputStream.close();
dataOutputStream.close();
} catch (final IOException e) {
LOGGER.warn("Could not close input/output streams: " + FormatData.formatStack(e));
}
dataInputStream = null;
dataOutputStream = null;
connect();
if (((dataInputStream != null) && (dataOutputStream != null)) || shouldTerminate) {
getNeedReconnect().set(false);
hardstandin = false;
synchronized (this) {
LOGGER.info("Sending notifyAll on channel");
this.notifyAll();
}
}
} // <== ORIGINAL CODE BLOCK ENDS HERE.
}
}
}
// *** shutdown the process
// need to shutdown the positiveBalance
// need to shut down each receive queuer
synchronized (this) {
LOGGER.info("Sending notifyAll on channel");
this.notifyAll();
}
// ***** 20130913 MS - Per Shannon's email, modify code to utilize the multiple connection code. *****
Iterator<ActiveSocket> it = activeSockets.iterator();
while (it.hasNext()) {
ActiveSocket activeSocket = it.next();
socket = activeSocket.getSocket();
// ORIGINAL CODE BLOCK STARTS HERE. ==>
if (socket != null) {
try {
socket.close();
} catch (final IOException ex) {
LOGGER.info(ERR_SOCKCLOSE);
}
}
// <== ORIGINAL CODE BLOCK ENDS HERE.
}
stopTimers();
terminated = true;
started = false;
if (internalTerminatedSignal != null) {
try {
internalTerminatedSignal.await(COUNTDOWN_WAIT_SECONDS, TimeUnit.SECONDS);
} catch (final InterruptedException e) {
LOGGER.info(FormatData.fullStackTrace(e));
}
}
if (terminatedSignal != null) {
LOGGER.info(this.getClass().getName() + " Updating countdown latch");
terminatedSignal.countDown();
}
}
Here is the connect() code:
public void connect() {
boolean clientSocket = false;
LOGGER.info("Connecting ... ");
while (!shouldTerminate) {
ActiveSocket activeSocket = null;
Socket newSocket = null;
int tries = 0;
int loopCounter = 0;
if (isServer) {
if (host == null) {
LOGGER.info("Must specify a host ip or host name with HOST configuration tag ");
return;
} else {
while (!shouldTerminate && (activeSockets.size() < this.maxActiveSockets)) {
activeSocket = new ActiveSocket(this);
newSocket = null;
if (serverSocket != null) {
try {
LOGGER.info("Accept socket.");
newSocket = serverSocket.accept();
} catch (final IOException ex) {
if (shouldTerminate) {
if (ex.getMessage() != null) {
LOGGER.info(ex.getMessage());
}
} else {
LOGGER.info("IOException while accepting connection.");
LOGGER.warn(FormatData.fullStackTrace(ex));
}
newSocket = null;
}
if (newSocket != null) {
try {
LOGGER.info("Server socket keepalive ... ");
newSocket.setKeepAlive(true);
if (newSocket.getKeepAlive()) {
LOGGER.info("Server socket keep alive to host (" + host + "," + port + ") for BankID:" + Integer.toString(this.getBankID()));
}
activeSocket.setSocket(newSocket);
activeSockets.add(activeSocket);
increaseConnects();
break;
} catch (final SocketException ex) {
LOGGER.info("SocketException while opening socket.");
LOGGER.warn(FormatData.fullStackTrace(ex));
newSocket = null;
}
}
} else { // first time through the loop
try {
LOGGER.info("Opening server socket (" + host + "," + port + ") for BankID:" + Integer.toString(this.getBankID()));
serverSocket = new ServerSocket(port);
} catch (final IOException ex) {
LOGGER.info("Unable to open server socket socket (" + host + "," + port + ")");
if (ex.getMessage().indexOf("Cannot assign requested address") > -1) {
this.terminate();
final String logMessage = "Invalid IP Address assigned:" + host + ",port:" + port;
final String subject = logMessage;
ATMServer.sendNotification(subject, logMessage);
} else if (tries == 0) {
tries++;
final String logMessage = "Unable to open server socket (" + host + "," + port + ")";
final String subject = "Unable to open server socket (" + host + "," + port + ")";
ATMServer.sendNotification(subject, logMessage);
}
LOGGER.warn(FormatData.fullStackTrace(ex));
}
}
}
}
} else { // client socket -- connecting to entity
clientSocket = true;
while (!shouldTerminate && (activeSockets.size() < this.maxActiveSockets)) {
activeSocket = new ActiveSocket(this);
newSocket = null;
if (this.isInForcedStandIn()) {
LOGGER.info("Forced standin " + getName());
try {
Thread.sleep(3000);
} catch (final InterruptedException ex) {
LOGGER.info("Interrupted while waiting for connection.");
LOGGER.warn(FormatData.fullStackTrace(ex));
}
} else {
if (!shouldTerminate) {
if ((loopCounter % 120) == 0) {
try {
LOGGER.info("Connecting to host (" + remoteHost + "," + remotePort + ") for BankID:" + Integer.toString(this.getBankID()));
newSocket = new Socket(InetAddress.getByName(remoteHost), remotePort);
if (newSocket.isConnected()) {
tries = 0;
LOGGER.info("Client socket connected to host (" + remoteHost + "," + remotePort + ") for BankID:" + Integer.toString(this.getBankID()));
}
newSocket.setKeepAlive(true);
if (newSocket.getKeepAlive()) {
LOGGER.info("Client socket keep alive to host (" + remoteHost + "," + remotePort + ") for BankID:" + Integer.toString(this.getBankID()));
}
activeSocket.setSocket(newSocket);
activeSockets.add(activeSocket);
increaseConnects();
break;
} catch (final IOException ex) {
loopCounter++;
tries++;
LOGGER.info("SocketException while opening remote socket (" + remoteHost + "," + remotePort + ") " + " " + ex.getClass() + " " + ex.getMessage());
if ((tries % 300) == 0) {
recordErrorToDatabase(ex.getMessage());
}
}
} else {
loopCounter++;
try {
synchronized (clientConnectLock) {
clientConnectLock.wait(1000);
}
} catch (final InterruptedException inex) {
LOGGER.info("SocketException while opening remote socket " + Thread.currentThread().getName());
LOGGER.warn(FormatData.fullStackTrace(inex));
if (!this.shouldTerminate) {
recordErrorToDatabase("InterruptedException without terminate set.");
}
}
}
}
}
}
}
try {
// here, if we created a new ActiveSocket, establish dataInput and dataOuput streams
// for Discover, this will mean adding up to MaxActiveSockets # of sockets to the activeSockets list.
// for each other SwitchChannel, this will be the only activeSocket
if (activeSocket != null) {
LOGGER.info("Creating serverIn/serverOut data streams " + Thread.currentThread().getName());
DataInputStream dataInputStream = new DataInputStream(new BufferedInputStream(newSocket.getInputStream()));
if (newSocket.isConnected()) {
LOGGER.info("socket still connected to host (" + remoteHost + "," + remotePort + ") for BankID:" + Integer.toString(this.getBankID()));
}
DataOutputStream dataOutputStream = new DataOutputStream(new BufferedOutputStream(newSocket.getOutputStream(), 2048));
activeSocket.setDataInputStream(dataInputStream);
activeSocket.setDataOutputStream(dataOutputStream);
//activeSockets.add(activeSocket);
activeSocket.setNumReceivers(this.numReceivers);
ReceiveQueuer[] receiveQueuers = activeSocket.getReceiveQueuers();
LOGGER.info("Starting receive queuers");
for (int cnt = 0; cnt < numReceivers; cnt++) {
receiveQueuers[cnt].setName(this.systemName + "-Socket-" + Integer.toString(activeSockets.size()) + "-ReceiveQueuer-" + Integer.toString(cnt));
receiveQueuers[cnt].setActiveSocket(activeSocket);
receiveQueuers[cnt].start();
}
}
if (clientSocket) {
break;
}
} catch (final Exception ex) {
LOGGER.info("Exception while creating input/output streams " + Thread.currentThread().getName());
LOGGER.warn(FormatData.fullStackTrace(ex));
}
}
if (!shouldTerminate) {
LOGGER.info("Socket connection complete " + Thread.currentThread().getName());
} else {
LOGGER.info("Stopped establishing socket connection " + Thread.currentThread().getName());
}
}
The easiest way to use multiple sockets is to allocate a new thread don't try to use different sockets on one thread you'll make it very hard for yourself
Related
I am trying to implement sample HTTP server using Java socket and executor service for concurrency. However every 2nd request is failing when I run the test using JMeter with 2 or more requests or browser for example.
How to properly handle the request? Here is the sample source code:
public class Service {
public static void main(String[] args) throws Exception {
var serverSocket = new ServerSocket(8080);
var executors = Executors.newFixedThreadPool(4);
while(true) {
try {
var server = serverSocket.accept();
executors.submit(() -> {
try {
var text = "sample";
System.out.println("Waiting for client on port " +
serverSocket.getLocalPort() + "...");
System.out.println("Getting empty request");
var response = "HTTP/1.1 200 OK\r\n" +
"Content-Type: text/plain\r\n" +
"Content-Length: " + text.length() + "\r\n\r\n"
+ text;
server.getOutputStream().write(response.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
System.out.println("Executor error:" + e.toString());
e.printStackTrace();
} finally {
try {
System.out.println("Closing server");
server.close();
} catch (Exception e) {
System.out.println("Executor error2: ");
e.printStackTrace();
}
}
});
} catch (Exception e) {
e.printStackTrace();
break;
}
}
serverSocket.close();
}
}
Your first problem lies in your response.
"HTTP/1.1 200 OK\r\n"
That allows for keep-alive, which you're not handling. A basic JMeter sampler tries to use keep alive, that is why you always fail on the second attempt.
You can change it to
"HTTP/1.0 200 OK\r\n"
That does not support keep alive, so you'll get a lot more successes with your current code. For me I only get a couple 1000 responses before JMeter has another error, but I don't know what the error is.
To support keep alive, I need to parse the request. Here is an example.
int clients = 0;
while(true) {
try {
System.out.println("Waiting for client on port " +
serverSocket.getLocalPort() + "...");
var server = serverSocket.accept();
final int client_no = clients++;
System.out.println("handling: " + client_no);
executors.submit(() -> {
int sent = 0;
try {
var is = server.getInputStream();
var os = server.getOutputStream();
var text = "sample";
byte[] tb = text.getBytes(StandardCharsets.UTF_8);
char[] buffer = new char[256];
int cr_count = 0;
while( true ){
int i=0;
int r = is.read();
if(r == -1) break;
while( r != -1 ){
char c = (char)r;
if( c == '\n' ){
cr_count++;
} else if( c != '\r' ){
cr_count = 0;
}
buffer[i++] = c;
if(cr_count == 2) break;
r = is.read();
}
//System.out.println("request: " + new String(buffer));
var response = "HTTP/1.1 200 OK\r\n" +
"Content-Type: text/plain\r\n" +
"Content-Length: " + tb.length + "\r\n\r\n";
os.write(response.getBytes(StandardCharsets.UTF_8));
os.write(tb);
os.flush();
sent++;
}
} catch (Exception e) {
System.out.println("Executor error:" + e.toString());
e.printStackTrace();
} finally {
try {
System.out.println("Closing connection!");
server.close();
} catch (Exception e) {
System.out.println("Executor error2: ");
e.printStackTrace();
}
System.out.println("sent " + sent + " responses to client " + client_no);
}
});
} catch (Exception e) {
e.printStackTrace();
break;
}
}
This will run a JMeter test for me. It can use either 1.0 or 1.1 and finish 10's of thousands of requests. If I use keep alive (1.1) each client handles many requests, if I don't use keep alive (1.0) each client handles 1 request.
If I dont read the request header, then the http 1.0 version will stop after a couple thousand requests.
It is also a separate issue from your original "dies after the second request." which is because your are not actually using HTTP 1.1 !
I have a threaded java client/server pair, and it's behaving really strange . Here is the server side :
public class sample_server {
private static int port=4444, maxConnections=0;
// Listen for incoming connections and handle them
public static void main(String[] args) {
int i=0;
try{
ServerSocket listener = new ServerSocket(port);
Socket server;
while((i++ < maxConnections) || (maxConnections == 0)){
doComms connection;
server = listener.accept();
doComms conn_c = new doComms(server);
Thread t = new Thread(conn_c);
t.start();
}
} catch (IOException ioe) {
System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
}
class doComms implements Runnable {
private Socket server;
private String line,input;
doComms(Socket server) {
this.server=server;
}
public void run () {
input="";
try {
// Get input from the client
DataInputStream in = new DataInputStream (server.getInputStream());
PrintStream out = new PrintStream(server.getOutputStream());
while((line = in.readLine()) != null && !line.equals(".")) {
java.util.Date date = new java.util.Date();
String timeString = String.valueOf((date.getTime()));
input=input + line + timeString;
out.println("I got:" + line + " " + timeString + "\n");
}
// Now write to the client
System.out.println("Overall message is:" + input);
out.println("Overall message is:" + input);
server.close();
} catch (IOException ioe) { /* ETC BOILERPLATE */
And this is my client code :
public class sample_client {
public static void main(String[] args) throws IOException {
String serverHostname = new String ("127.0.0.1");
if (args.length > 0)
serverHostname = args[0];
System.out.println ("Attemping to connect to host " +
serverHostname + " on port 10007.");
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
// echoSocket = new Socket("taranis", 7);
echoSocket = new Socket(serverHostname, 4444);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
echoSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: " + serverHostname);
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for "
+ "the connection to: " + serverHostname);
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(
new InputStreamReader(System.in));
String userInput;
System.out.print ("input: ");
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
System.out.println("echo: " + in.readLine());
System.out.print ("input: ");
}
out.close();
in.close();
stdIn.close();
echoSocket.close();
//END OLD CODE
}
}
When I run this code, on the clients it only displays the full "echo" line on every other round, like so :
input: hi
echo: I got:hi 1430872840921
input: ok
echo:
input: hi
echo: I got:ok 1430872842861
input: ok
echo:
input: hi
echo: I got:hi 1430872846214
input: ok
echo:
input:
thanks
PrintStream out = new PrintStream(server.getOutputStream());
You need the autoflush parameter here too, just as in the client where you construct the PrintWriter.
Or else call flush() after every println() in the server, if you can be bothered.
client server chat system as server start the server and client connect to the server..when client tries to connect to server, it success but the array goes to lost connection condition.
catch (Exception ex) {
outputTextArea.append("Lost a connection. \n");
ex.printStackTrace();
clientOutputStreams.remove(client);
anyway to fix it?
Server side code
public ClientHandler(Socket clientSocket, PrintWriter user) {
// new inputStreamReader and then add it to a BufferedReader
client = user;
try {
sock = clientSocket;
InputStreamReader isReader = new InputStreamReader(sock.getInputStream());
reader = new BufferedReader(isReader);
} // end try
catch (Exception ex) {
outputTextArea.append("Error beginning StreamReader. \n");
} // end catch
} // end ClientHandler()
public void run() {
String message, connect = "Connect", disconnect = "Disconnect", chat = "Chat" ;
String[] data;
try {
while ((message = reader.readLine()) != null) {
outputTextArea.append("Received: " + message + "\n");
data = message.split(":");
for (String token:data) {
outputTextArea.append(token + "..\n");
}
if (data[2].equals(connect)) {
tellEveryone((data[0] + ":" + data[1] + ":" + chat));
userAdd(data[0]);
} else if (data[2].equals(disconnect)) {
tellEveryone((data[0] + ":has disconnected." + ":" + chat));
userRemove(data[0]);
} else if (data[2].equals(chat)) {
tellEveryone(message);
} else {
outputTextArea.append("No Conditions were met. \n");
}
} // end while
} // end try
catch (Exception ex) {
outputTextArea.append("Lost a connection. \n");
ex.printStackTrace();
clientOutputStreams.remove(client);
} // end catch
} // end run()
public void userAdd (String data) {
String message, add = ": :Connect", done = "Server: :Done", name = data;
outputTextArea.append("Before " + name + " added. \n");
userlist.add(name);
outputTextArea.append("After " + name + " added. \n");
String[] tempList = new String[(userlist.size())];
userlist.toArray(tempList);
for (String token:tempList) {
message = (token + add);
tellEveryone(message);
}
tellEveryone(done);
}
public void userRemove (String data) {
String message, add = ": :Connect", done = "Server: :Done", name = data;
userlist.remove(name);
String[] tempList = new String[(userlist.size())];
userlist.toArray(tempList);
for (String token:tempList) {
message = (token + add);
tellEveryone(message);
}
tellEveryone(done);
}
public void tellEveryone(String message) {
// sends message to everyone connected to server
Iterator it = clientOutputStreams.iterator();
while (it.hasNext()) {
try {
PrintWriter writer = (PrintWriter) it.next();
writer.println(message);
writer.flush();
outputTextArea.setCaretPosition(outputTextArea.getDocument().getLength());
} // end try
catch (Exception ex) {
outputTextArea.append("Error telling everyone. \n");
} // end catch
} // end while
} // end tellEveryone()
errors
java.lang.ArrayIndexOutOfBoundsException: 2
at chatsystemserver.ServerSide$ClientHandler.run(ServerSide.java:55)
at java.lang.Thread.run(Thread.java:745)
any idea how to fix the data[2]?
Check if the array has at least 3 elements. That is, change
if (data[2].equals(connect)) {
to
if (data.length > 2 && data[2].equals(connect)) {
I'm trying to get a live flash that lives on a webserver to talk to a local java server, that will live on the clients PC.
I'm trying to achieve this with a socket connection. (port 6000)
Now, at first flash was able to connect, but it just sends <policy-file-request/>. After this nothing happens.
Now, some people at Kirupa suggested to send an cross-domain-policy xml as soon as any connection is established from the java side. http://www.kirupa.com/forum/showthread.php?t=301625
However, my java server just throws the following:
End Exception: java.net.SocketException: Software caused connection abort: recv failed
I've already spend a great amount of time on this subject, and was wondering if anyone here knows what to do?
I found the anwser, So ill post it here in case someone with a simmilar question finds this post.
The moment Flash connects to a local socket server it will send the following:
<policy-file-request/>
We will have to answer with a policy file and immediatly close the connection.
Java:
import java.net.*;
import java.io.*;
public class NetTest {
public static void main(String[] args) {
ServerSocket serverSocket = null;
/* Open a socket to listen */
try {
serverSocket = new ServerSocket(6000);
} catch (IOException e) {
System.out.println("Could not listen on port: 6000");
System.exit(-1);
}
// Try catch a socket to listen on
Socket clientSocket = null;
try {
System.out.println("Waiting for auth on 6000...");
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.out.println("Accept failed: 6000");
System.exit(-1);
}
// Now a stream has been opened...
InputStream in = null;
OutputStream out = null;
try {
in = clientSocket.getInputStream();
out = clientSocket.getOutputStream();
} catch (IOException e) {
System.out.println("Failed to get streams.");
System.exit(-1);
}
System.out.println("Socket connection incoming!");
// Keep going while we can...
byte b[] = new byte[100];
int offset = 0;
String s;
try {
boolean done = false;
boolean auth = false;
String protocol_target = "<policy-file-request/>";
byte[] p_bytes = protocol_target.getBytes();
int result;
while (!done) {
if (in.read(b, offset, 1) == -1)
done = true;
else {
if (!auth) {
++offset;
b[offset] = 0;
if (offset != p_bytes.length) {
System.out.println("Waiting for protocol data... ("
+ offset + "/" + p_bytes.length + ")");
} else {
// Compare byte data
for (int i = 0; i < p_bytes.length; ++i) {
System.out.print(b[i] + " ");
}
System.out.print("\n");
System.out.flush();
for (int i = 0; i < p_bytes.length; ++i) {
System.out.print(p_bytes[i] + " ");
}
System.out.print("\n");
System.out.flush();
boolean match = true;
for (int i = 0; i < p_bytes.length; ++i) {
if (b[i] != p_bytes[i]) {
match = false;
System.out
.println("Mismatch on " + i + ".");
}
}
if (match)
auth = true;
else {
System.out.println("Bad protocol input.");
System.exit(-1);
}
}
// Auth
if (auth) {
System.out.println("Authing...");
s = "<?xml version=\"1.0\"?><cross-domain-policy><allow-access-from domain='*' to-ports='6000' /></cross-domain-policy>";
b = s.getBytes();
out.write(b, 0, b.length);
b[0] = 0;
out.write(b, 0, 1); // End
out.flush();
offset = 0;
b = new byte[100];
b[0] = 0;
auth = true;
System.out.println("Auth completed.");
}
}
}
}
} catch (IOException e) {
System.out.println("Stream failure: " + e.getMessage());
System.exit(-1);
}
// Finished.
try {
in.close();
out.close();
clientSocket.close();
} catch (Exception e) {
System.out.println("Failed closing auth stream: " + e.getMessage());
System.exit(-1);
}
// Try catch a socket to listen on for data
try {
System.out.println("Waiting on 6000 fo data...");
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.out.println("Accept failed: 6000");
System.exit(-1);
}
// Now a stream has been opened...
in = null;
out = null;
try {
in = clientSocket.getInputStream();
out = clientSocket.getOutputStream();
} catch (IOException e) {
System.out.println("Failed to get streams.");
System.exit(-1);
}
System.out.println("Socket data connection waiting.");
// Echo
try {
boolean done = false;
while (!done) {
if (in.read(b, offset, 1) == -1)
done = true;
else {
b[1] = 0;
s = new String(b);
System.out.print(s);
System.out.flush();
}
}
} catch (IOException e) {
System.out.println("Failed echo stream: " + e.getMessage());
System.exit(-1);
}
// Finished.
try {
in.close();
out.close();
clientSocket.close();
serverSocket.close();
} catch (Exception e) {
System.out.println("Failed closing stream: " + e.getMessage());
System.exit(-1);
}
}
}
this is my Main class which belongs to the server application! but it is really surprizing that without running the client application,these sentences will be written in the console.would you please help me why?thanks.
my Main class:
public class Main {
static Socket client = null;
static ServerSocket server = null;
// We can have 10 clients' connections
static ClientThread t[] = new ClientThread[10];
public static void main(String args[]) {
System.out.println("Server is starting...");
System.out.println("Server is listening...");
try {
server = new ServerSocket(5050);
System.out.println("Client Connected...");
while (true) {
client = server.accept();
for (int i = 0; i <= 9; i++) {
if (t[i] == null) {
(t[i] = new ClientThread(client, t)).start();
break;
}
}
}
} catch (IOException e) {
System.out.println(e);
}
}
}
// This client thread opens the input and the output streams for a particular client,
// ask the client's name, informs all the clients currently connected to the
// server about the fact that a new client has joined the chat room,
// and as long as it receive data, echos that data back to all other clients.
// When the client leaves the chat room this thread informs also all the
// clients about that and terminates.
class ClientThread extends Thread {
DataInputStream is = null;
PrintStream os = null;
Socket clientSocket = null;
ClientThread t[];
public ClientThread(Socket clientSocket, ClientThread[] t) {
this.clientSocket = clientSocket;
this.t = t;
}
#Override
public void run() {
String line;
String name;
try {
is = new DataInputStream(clientSocket.getInputStream());
os = new PrintStream(clientSocket.getOutputStream());
os.println("Enter your name.");
name = is.readLine();
os.println("Hello " + name + " to our chat room.\nTo leave enter /quit in a new line");
for (int i = 0; i <= 9; i++) {
if (t[i] != null && t[i] != this) {
t[i].os.println("*** A new user " + name + " entered the chat room !!! ***");
}
}
while (true) {
line = is.readLine();
if (line.startsWith("/quit")) {
break;
}
for (int i = 0; i <= 9; i++) {
if (t[i] != null) {
t[i].os.println("<" + name + "> " + line);
}
}
}
for (int i = 0; i <= 9; i++) {
if (t[i] != null && t[i] != this) {
t[i].os.println("*** The user " + name + " is leaving the chat room !!! ***");
}
}
os.println("*** Bye " + name + " ***");
// Clean up:
// Set to null the current thread variable such that other client could
// be accepted by the server
for (int i = 0; i <= 9; i++) {
if (t[i] == this) {
t[i] = null;
}
}
// close the output stream
// close the input stream
// close the socket
is.close();
os.close();
clientSocket.close();
} catch (IOException e) {
System.out.println(e);
}
}}
in the console:
init:
deps-jar:
compile-single:
run-single:
Server is starting...
Server is listening...
Client Connected...
you create a Socket and declare that the client is connected before accepting a connection :
server = new ServerSocket(5050);
System.out.println("Client Connected...");
you should print
client is connected
after this line
client = server.accept();
which blocks until a client actually connects