I am learning networking in Java. I tried a code that uses the ServerSocket class. But the serversocket is not able to establish a connection every time. I tried various port numbers, longer timeouts, but nothing works. Here is my code for the Server:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.*;
class TestServer extends Thread
{
private ServerSocket serverSocket;
public TestServer(int port) throws IOException
{
serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(60000);
}
public void run()
{
while(true)
{
try
{
System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
Socket socket = serverSocket.accept();
System.out.println("Just connected to " + socket.getRemoteSocketAddress());
DataInputStream in = new DataInputStream(socket.getInputStream());
System.out.println(in.readUTF());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeUTF("Thanks for connecting to " + socket.getLocalSocketAddress() + "\nGoodbye!" );
socket.close();
}
catch(SocketTimeoutException e)
{
System.out.println("Socket timed out");
break;
}
catch(IOException e)
{
e.printStackTrace();
break;
}
}
}
}
The TestServer class performs both client and server side operations on the run function being called. I don't get where am I going wrong. My class containing main function is:
import java.io.IOException;
class Main
{
public static void main(String[] args) throws IOException
{
int port = Integer.parseInt(args[0]);
TestServer server = new TestServer(port);
server.start();
}
}
I am new to Java networking, so please be considerate about some silly mistake and let me know what have I done wrong.
Related
I have a socket programming code that goes..
Server Program
import java.net.*;
import java.io.*;
public class GreetingServer extends Thread
{
private static int port;
private ServerSocket serverSocket;
public GreetingServer(int port) throws IOException
{
serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(50000);
}
public void run()
{
while(true)
{
try
{
System.out.println("Waiting for client on port " +
serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
System.out.println("Just connected to "
+ server.getRemoteSocketAddress());
DataInputStream in =
new DataInputStream(server.getInputStream());
System.out.println(in.readUTF());
DataOutputStream out =
new DataOutputStream(server.getOutputStream());
out.writeUTF("Thank you for connecting to "
+ server.getLocalSocketAddress() + "\nGoodbye!");
server.close();
}catch(SocketTimeoutException s)
{
System.out.println("Socket timed out!");
break;
}catch(IOException e)
{
e.printStackTrace();
break;
}
}
}
public static void main(String [] args)
{
port=9000;
try
{
Thread t = new GreetingServer(port);
t.start();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
And the client side code that is...
import java.io.*;
import java.net.*;
public class GreetingClient
{
private static String serverName;
public static void main(String [] args)
{
String sName = "MyServerName";
int port = 9000;
try
{
System.out.println("Connecting to " + sName
+ " on port " + port);
Socket client = new Socket(sName, port);
System.out.println("Just connected to "
+ client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out =
new DataOutputStream(outToServer);
out.writeUTF("Hello from "
+ client.getLocalSocketAddress());
InputStream inFromServer = client.getInputStream();
DataInputStream in =
new DataInputStream(inFromServer);
System.out.println("Server says " + in.readUTF());
client.close();
}catch(IOException e)
{
}
}
}
The code compiles fine. But when i run the program, first the server and then the client, the server displays that
Waiting for client on port 9000...
Socket timed out!
and the client shows
Connecting to MyServerName on port 9000
What is wrong with the code?? I have tried increasing and decreasing the timeout values but it gives the same output.
What is wrong with the code?
There's nothing wrong with your code. You set a 50 second accept timeout, accept blocked for 50 seconds without a client trying to connect, so a SocketTimeoutException was thrown. Everything here is working as designed.
Of course it's possible that:
your accept timeout is too short
you don't want to abort your server just because of an accept timeout
you don't want an accept timeout at all.
All of these are design decisions that depend on your requirements.
It's also possible that you got the host name wrong in the client, but as you're ignoring exceptions in the client:
catch(IOException e)
{
}
there is no way you will ever find out. Never ignore IOExceptions.
Above code is perfectly working with sName in client as 'localhost', since I am running both client and server in my local:
String sName = "localhost";
Verify your server-name if you are expecting client to connect to server.
Client Class
import java.io.PrintWriter;
import java.net.Socket;
public class Client
{
public static void main(String[] args)
{
try
{
System.out.println(" Starting Client ");
Socket socket = new Socket ("localhost",55555);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(),true);
printWriter.println("Hello from client");
printWriter.println("Conected, Yes!");
socket.close();// Changes as suggested by Jack
}
catch (Exception e)
{
System.out.println(e);
}
}
}
Server Class
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class Server
{
public static void main(String[] args)
{
System.out.println(" inside main ");
try
{
System.out.println("Starting Server");
ServerSocket serverSocket= new ServerSocket(55555);
Socket clientSocket = serverSocket.accept();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine;
while ((inputLine= bufferedReader.readLine())!=null)
System.out.println("Server Message:"+inputLine);
}
catch (IOException e)
{
System.out.println("IOException "+e);
}
}
}
Output:
Starting Server
Server Message:Hello from client
Server Message:Conected, Yes!
IOException java.net.SocketException: Connection reset
Client and Server java files are in the same package.
What would trigger IOException in the following code?
Is it something to do with Eclipse?
FYI, I am using Eclipse SDK
Version: 4.2.2
Build id: M20130204-1200
The problem is that your client opens a Socket, sends some data and then exits the program, thus abruptly closing the connection.
You should call close() on the Socket from the client side to notify the server that the socket it is going to be closed.
As #Jack mentioned in his answer you need to close() your socket before the client application exit.
Socket is AutoCloseable
The safe way of work with closable resource is creation in try block:
public class Client {
public static void main(String[] args) {
System.out.println(" Starting Client ");
try(Socket socket = new Socket("localhost", 55555)) {
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.println("Hello from client");
printWriter.println("Conected, Yes!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
and it will be closed automatically on exit (from try section).
Here's my code:
SERVER:
package server;
public class Main {
public static void main(String args[]) {
new EchoServer(9000);
}
}
+
package server;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class EchoServer {
private ServerSocket server;
public EchoServer(int port) {
try {
server = new ServerSocket(port);
while (true) {
Socket socket = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println(in.readLine() + " | MOD");
socket.close();
}
} catch(Exception err) {
err.printStackTrace();
}
}
}
CLIENT:
package client;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Main {
public static void main(String args[]) {
try {
while (true) {
Socket socket = new Socket("localhost", 9000);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
out.println(input.readLine());
System.out.println(in.readLine());
socket.close();
}
} catch (Exception err) {
System.out.println(err);
}
}
}
It works all as it should, except that I want when the server sends the "message" + " | MOD" to the client, I want the server to send that to all clients, how can I do that?
I am new to Java, but not to coding so please help me if I've done some wrong stuff that can be done easier or better.
Please help.
Thanks alot.
What you can do is save the client sockets in an array, and then use a for loop to send to each socket.
First, declare your clientSocket array; note that 5 is just an arbitrary size used for testing. Also, declare a counter int.
public Socket clientSocket[] = new Socket[5];
public int intLastSocket = 0;
// this should be placed where you're waiting to accept connections
while (true) {
printTCP("Ready to accept welcome socket");
clientSocket[intLastSocket] = welcomeSocket.accept();
intLastSocket++;
}
// on the server, call this to send. s is a reference to the server object
public void sendToAllTCP(TCPServer s, String message) {
for (Socket z : s.clientSocket) {
if (z != null) {
PrintStream outToClient = null;
try {
outToClient = new PrintStream(z.getOutputStream());
outToClient.println(message);
} catch (IOException e) {
TCPServer.printTCP("Caught an IO exception trying "
+ "to send to TCP connections");
e.printStackTrace();
}
}
}
}
IN YOUR CODE:
package com.murplyx.server;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class EchoServer {
private ServerSocket server;
// use the clientSocket Array to save each new connection
public Socket clientSocket[] = new Socket[5];
public EchoServer(int port) {
try {
server = new ServerSocket(port);
// this should be placed where you're waiting to accept connections
while (true) {
System.out.println("Ready to accept welcome socket");
clientSocket[intLastSocket] = server.accept();
intLastSocket++;
//send your message here, note that putting
//it here will send it each time u add a new connection
sendToAllTCP(/*the message you want to send */);
}
} catch(Exception err) {
err.printStackTrace();
}
}
public void sendToAllTCP(String message) {
// this is an enchanced for loop, i don't know if it's in other languages
// but in java it's supposed to let you loop through
//each object in any iterable list
// such as array, arraylist, linkedlist, etc
for (Socket z : clientSocket) {
if (z != null) {
//basically this chunk of code declares output and input streams
//for each socket in your array of saved sockets
PrintStream outToClient = null;
try {
outToClient = new PrintStream(z.getOutputStream());
outToClient.println(message);
} catch (IOException e) {
System.out.println("Caught an IO exception trying "
+ "to send to TCP connections");
e.printStackTrace();
}
}
}
}
}
Depending on when you want to send your message, you can use the console and sys.in to send it. For example, if you read a line from sys.in and it .equals("sendMsg"), then you can call sendToAllTCP(yourmessage)
You should take a look at multiThreaded chat Server. Each client wich connects gets it's own thread.
Here is the perfect answer to your question:
multithread client-server chat, using sockets
Good luck mate!
I'm a beginner (as you can probably tell) and I'm having issues establishing a connection from my very simple client to my very simple server. My server starts up fine as it creates a serversocket that listens on port 43594. However, when I run my client to try to establish a connection, an IOException is thrown by my client as it tries to connect.
I'm doing java in my spare time as a hobby, so I'd really appreciate if someone could help me understand what's going on, where I'm going wrong (or if I'm even going right any where) so as to help me improve.
Here is my Server code:
package src.org;
import java.io.FileInputStream;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.net.*;
import java.io.*;
public class Server {
private static final Logger logger = Logger.getLogger(Server.class.getName());
private final static void createSocket(int portNumber) throws IOException
{
ServerSocket serverSocket = new ServerSocket(portNumber);
Socket clientSocket = serverSocket.accept();
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
}
public static void main(String... args)
{
logger.info("Starting server...");
Properties properties = new Properties();
logger.info("loading settings...");
try
{
properties.load(new FileInputStream("settings.ini"));
Constants.GAME_NAME = properties.getProperty("name");
Constants.PORT = Integer.valueOf(properties.getProperty("port"));
} catch(Exception ex)
{
ex.printStackTrace();
}
logger.info("Creating sockets...");
try
{
logger.info("Socket created. Listening on port: " + Constants.PORT);
createSocket(Constants.PORT);
} catch(Exception ex)
{
logger.log(Level.SEVERE, "Error creating sockets.", ex);
System.exit(1);
}
}
}
Which (to my knowledge) seems to be doing its job.
And here's what I believe to be the culprit class, the client class:
import java.io.*;
import java.net.*;
public class Client {
//private static final String hostName = Constants.HOST_NAME;
//private static final int portNumber = Constants.PORT;
private static final String hostName = "localhost";
private static final int portNumber = 43594;
public static void main(String... args)
{
try (
Socket socket = new Socket(InetAddress.getLocalHost(), portNumber); // using localhost at the moment
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
) {
System.out.println("Client socket created.");
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer, fromUser;
while((fromServer = in.readLine()) != null)
{
System.out.println("Server:" + fromServer);
fromUser = stdIn.readLine();
if(fromUser != null) {
System.out.println("Client: " + fromUser);
out.println(fromUser);
}
}
} catch(UnknownHostException ex) {
System.err.println("Unknown host: " + hostName);
System.exit(1);
} catch(IOException ioe) {
System.err.println("Couldn't get i/o from: " + hostName);
System.out.println("Error:" + ioe.getMessage());
System.exit(1);
}
}
}
When I ping localhost I get a response; the port on both sides is 43594 and the host is just local. The command line response from the client is:
Client socket created
Couldn't get i/o from: localhost
Error: connection reset
Press any key to continue...
I'm sorry in that I know this would be a very simple fix to many of you, but I can't seem to find an answer or fix it myself. Any insight or help would be greatly appreciated. Cheers.
Sorry if I've left out any other important pieces of information.
You've left out much of the code. The part in the server that sends data on the accepted socket. So the method that calls accept() just exits, the socket is garbage-collected, and closed, and the client keeps doing I/O to the other end of the connection, which is invalid,so you get an exception.
Environment: Java 6, windows xp
I am trying to write a client-server TCP socket application. Need to detect on the server, when the client has closed the socket. All the information on the Internet, says that the server will throw a socket exception when its not able to write.
However, when I run the code (see below), I see that the server gets the exception only when the client doesn't read anything from the stream. When the client reads from the input stream, no exception is thrown on the server.
can someone please tell me the right way to detect a client side socket close (and also explain the behavior exhibited by the code below)?
Code:
package com.connection;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
public class Test implements Runnable{
ServerSocket ss = null;
public Test() throws Exception{
ss = new ServerSocket(9999);
}
public void run(){
try{
Socket s = ss.accept();
Writer w = new OutputStreamWriter(s.getOutputStream());
w.write("Hello\n");
w.flush();
System.out.println("Server: wrote string 1");
System.out.println("Server: sleeping...");
Thread.sleep(5000);
System.out.println("Server: woke up");
w.write("Hello\n");
w.flush();
System.out.println("Server: wrote string 2");
}catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception{
Thread server = new Thread(new Test());
server.start();
Thread client = new Thread(new TestClient());
client.start();
}
}
class TestClient implements Runnable{
public void run() {
try {
Socket s = new Socket("localhost", 9999);
// Comment out the below 4 lines to see the write exception on server
BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));
System.out.println("Client: reading input...");
String str = r.readLine();
System.out.println(str);
// Comment the *above* 4 lines to see exception on server
Thread.sleep(1000);
System.out.println("Client: woke up");
s.close();
System.out.println("Client: socket closed");
}catch(Exception e){
e.printStackTrace();
}
}
}