I got a program which listens to connections from a client.
import java.io.*;
import java.net.*;
class SocketExampleServer {
public static void main(String [] args) throws Exception {
int port = 5665;
ServerSocket ss = new ServerSocket(port);
System.out.println("Waiting incoming connection...");
Socket s = ss.accept();
DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream out = new DataOutputStream(s.getOutputStream());
String x = null;
try {
while ((x = dis.readUTF()) != null)
{
System.out.println(x);
out.writeUTF(x.toUpperCase());
}
}
catch(IOException e)
{
System.err.println("Client closed its connection.");
}
catch(Exception e)
{
System.err.println("Unknown exception");
}
s.close();
ss.close();
dis.close();
out.close();
System.exit(0);
}
}
The things is that at this point
System.out.println(x);
out.writeUTF(x.toUpperCase());
only the second line is executed. If you swap the line once a gain only the second line is executed. What is the reason for that?
And one more thing when I run the program second time it throws this error:
Exception in thread "main" java.net.SocketException: Unrecognized Windows Sockets error: 0: JVM_Bind
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.bind(Unknown Source)
at java.net.ServerSocket.bind(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at SocketExampleServer.main(SocketExampleServer.java:9)
Once I change the port number to a new one it runs for a one time and the next time you need to update the port number if you want to run it again. I did not get the reason for that cause I close the socket and in my opinion the port shall stay free for the next run up.
On the 2nd question:
Not sure what is causing that, but to avoid the possibility of a non-checked exception thrown by your code is the reason, you should close your resources in a finally clause:
ServerSocket ss;
try {
...
}
finally {
if (ss.close() != null) {
ss.close();
}
}
Related
I started learning about networking, sockets three days ago, and I started understanding a few things after I moved to using eclipse IDE.
I managed to get the client to work, basically send the input to the server, but when I do so i get the following error:
java.net.SocketException: Connection reset
That's the full log of the server:
Server started.
Connected: /127.0.0.1:57276
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at Server.run(Server.java:31)
at Server.main(Server.java:22)
Line 31:
in = input.readLine();
Line 22:
run();
I am probably not reading the I/O correctly, I didn't really look at "many" examples, I tried to get it myself and learn from my errors.
Can someone explain what happens here? why does the connection reset?
Server:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
public class Server {
private static ServerSocket socket;
private static PrintWriter output;
private static BufferedReader input;
private static Socket socketClient;
public static void main(String[] args) {
try {
System.out.println("Server started.");
socket = new ServerSocket(43537);
socketClient = socket.accept();
output = new PrintWriter(socketClient.getOutputStream());
input = new BufferedReader(new InputStreamReader(socketClient.getInputStream()));
System.out.println("Connected: " + socketClient.getRemoteSocketAddress().toString());
run();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void run() throws IOException {
String in;
while (socketClient.isConnected()) {
in = input.readLine();
if (in != null) {
System.out.println(in);
}
}
}
}
Client:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
import java.util.Scanner;
public class build {
/**
* #param args
* #throws IOException
* #throws UnknownHostException
*/
public static void main(String[] args) {
try {
System.out.println("Client started");
Socket sock = new Socket("localhost", 43537);
Scanner scanner = new Scanner(System.in);
String input;
PrintWriter out = new PrintWriter(sock.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
input = scanner.nextLine();
if (input != null) {
out.print(input);
}
if (reader.toString() != null) {
System.out.println(reader.toString());
}
} catch (IOException e) {
System.out.println("Client error");
}
}
}
Your client have written the data from kbd to socket and closed the socket by the time server tries to read message at line 31. Seems it's because you mistakenly did reader.toString() in client instead of reader.readLine(). readLine() will make client to stay online until response from server is received (or server is shut down).
In client you need to change to
if (input != null) {
out.println(input);
out.flush();
}
println(), not print(), because you use readLine() on server side, which won't return until it sees \n;
even with that you need out.flush() to send data to network;
You need to flush() your streams, close() your streams and close() your sockets. You've been reading a crappy tutorial if it didn't teach you this.
I am probably not reading the I/O correctly, I didn't really look at
"many" examples, I tried to get it myself and learn from my errors.
Maybe you should rethink your learning strategy.
The first thing I see is that your Client reads exactly one line of input, sends it to the server and then the program terminates thus closing the socket - which is what the error message says.
I can`t understand something simple. I have a class that handles the socket input. I have a catch-clause:
public class EntryPoint implements Runnable {
private Socket socket = null;
private BufferedReader br = null; // receives data from the destination
...
public void run() {
String command = null; // buffer for holding one request from command line
StringReader commandReader = null; // stream for reading command
try {
while (!socket.isClosed() && (command = br.readLine()) != null) {
try {
command = command.trim();
commandReader = new StringReader(command);
Request req = JAXB.unmarshal(commandReader, Request.class);
commandReader.close();
dispatcher.sendRequest(req);
} catch(DataBindingException ex) {
response.sendResponse(SystemMessageFactory.INVALID);
response.sendResponse(SystemMessageFactory.SOCKET_SHUTDOWN);
}
}
} catch (SocketException e) {
System.out.println("Socket Exception");
} catch (IOException e) {
Logger.getLogger("server").log(Level.SEVERE,
"Error reading the command input of the client!", e);
}
}
}
When the peer abruptly shuts down the socket, the connection reset is sent. The stack trace is:
16.07.2013 1:39:51 EntryPoint run
SEVERE: Error reading the command input of the client!
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:168)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at blood.steel.server.EntryPoint.run(EntryPoint.java:36)
at java.lang.Thread.run(Thread.java:662)
How is it possible? I am catching it twice! SocketException is caught in its own catch-clause and in IOException catch clause. But nothing happens! It does not catch the socket exception. How can I handle it and what is the cause of such behaviour?
Either the SocketExceptioon is not the one in java.net. Check your imports.
Or you are not running the code you think you are.
How to restart ServerSocket after IOException?
My server socket sometimes gets an EOFException and then stops accepting new connections. To solve this I have tried closing the old server socket and creating a new one after the exception is thrown. However even after the new server socket is created, new connections are not accepted. Can some one see why this does not work?
public Server() throws IOException {
try {
listen(port);
}
catch (IOException e) {
System.out.println("Server() - IO exception");
System.out.println(e);
/*when an exception is caught I close the server socket and try opening it a new one */
serverSocket.close();
listen(port);
}
}
private void listen(int port) throws IOException {
serverIsListening = true;
serverSocket = new ServerSocket(port);
System.out.println("<Listening> Port: " + serverSocket);
while (serverIsListening) {
if (eofExceptionThrown){ //manually triggering an exception to troubleshoot
serverIsListening = false;
throw new EOFException();
}
//accept the next incoming connection
Socket socket = serverSocket.accept();
System.out.println("[New Conn] " + socket);
ObjectOutputStream oOut = new ObjectOutputStream(socket.getOutputStream());
// Save the streams
socketToOutputStreams.put(socket, oOut);
// Create a new thread for this connection, and put it in the hash table
socketToServerThread.put(socket, new ServerThread(this, socket));
}
}
2x entry point , one form catch: never ends well.
try {
listen(port);
}
catch (IOException e) {
System.out.println("Server() - IO exception");
System.out.println(e);
/*when an exception is caught I close the server socket and try opening it a new one */
serverSocket.close();
listen(port);
}
I would do in a loop, while a boolean is true:
while(needToListen){
try{
listen(port)
}catch(Exception ex){
if(exception is what needed to break the loop, like a message has a string on it){
break;
}
}
}
if(needToListen){
Log.e("something unexpected, unrecoverable....");
}
My server socket sometimes gets an EOFException and then stops accepting new connections
No it doesn't. ServerSockets never get EOFExceptions. Rather, one of your accepted Sockets is getting an EOFException, which is only to be expected, and you are closing both that Socket, which is correct, and the ServerSocket, which is incorrect. Exceptions on accepted sockets don't affect the listening socket.
I have the follwing code which is a thread pool in java which accepts only one client
public class ServerThread implements Runnable {
ServerSocket serverSocket;
Socket clientSocket;
protected boolean isStopped = false;
int serverPort = 6500;
private String serverIpAddress = "127.0.0.1";
DataInputStream is;
ObjectOutputStream os=null;
protected BlockingQueue queue = null;
protected ExecutorService threadPool2 =
Executors.newFixedThreadPool(1);
public ServerThread(BlockingQueue queue) {
this.queue=queue;
}
public void run() {
try {
InetSocketAddress serverAddr = new InetSocketAddress(serverIpAddress, serverPort);
serverSocket = new ServerSocket();
serverSocket.bind(serverAddr);
System.out.println("s-a creat");
} catch (UnknownHostException e) {
System.err.println("Don't know about host");
} catch (IOException e) {
e.printStackTrace();
}
while(!isStopped()){
clientSocket=null;
try{
clientSocket = serverSocket.accept();
}
catch(Exception e)
{
e.printStackTrace();
}
WorkerServerRunnable workerRunnable = new WorkerServerRunnable(queue,clientSocket);
this.threadPool2.execute(workerRunnable);
}
this.threadPool2.shutdown();
System.out.println("Server Stopped.");
}
private synchronized boolean isStopped(){
return this.isStopped;
}
public synchronized void stop() {
this.isStopped = true;
try {
this.serverSocket.close();
} catch (IOException e) {
throw new RuntimeException("Error closing server", e);
}
}
}
But the problem is that I cannot get my server in ON state.
I mean once I press run I get the following error:
java.net.SocketException: Socket is not bound yet
at java.net.ServerSocket.accept(Unknown Source)
at servers.ServerThread.run(ServerThread.java:60)
at java.lang.Thread.run(Unknown Source)
java.net.BindException: Address already in use: JVM_Bind
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.bind(Unknown Source)
at java.net.ServerSocket.bind(Unknown Source)
at java.net.ServerSocket.bind(Unknown Source)
at servers.ServerThread.run(ServerThread.java:44)
at java.lang.Thread.run(Unknown Source)
Even if I shutdown my whole app and run it again still the same error....has anyone any idea why?Thank u!
Some other program is already using port 6500. Check that you're not running another instance of your program.
Try running
netstat -lp
to see what processes are using which ports. Make sure the port on which you wish to listen is not listed in the output from netstat.
In the run() method, when you are creating a ServerSocket and assigning it to serverSocket variable:
serverSocket = new ServerSocket();
Please give a port number in the ServerSocket constructor, like 5000
serverSocket = new ServerSocket(5000);
I am making a prototype client & server so that I can understand how to handle reconnects.
The server ought to create a serversocket and listen forever. A client may connect, send its data, and close its socket but it will not send a "I'm done and closing" type message to the server. For this reason, the server gets a EOFException when it does a readByte() since the remote client has closed. In the error handler for the EOFException, it will close the socket and open a new one.
Here's the problem: The client sometimes gets a SocketWriteError when it does the outputStream.write() call even after it successfully opens the socket/inputstream/outpustream. It may have something to do with the frequency that I'm opening and closing these sockets. One interesting thing is that the client does an arbitrary number of writes/close/reconnects before crapping out. It will sometimes crap out on the first reconnect, other times it will take 50 reconnects before seeing the SocketWriteError.
Here's the error on the client side:
java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:115)
at bytebuffertest.Client.main(Client.java:37)
Here are some snippets of code:
SERVER:
public static void main(String[] args)
{
Server x = new Server();
x.initialize();
}
private void initialize()
{
ServerSocket s;
InputStream is;
DataInputStream dis;
while (true) //ADDED THIS!!!!!!!!!!!!!!!!!!!!!!
{
try
{
s = new ServerSocket(4448);
s.setSoTimeout(0);
s.setReuseAddress(true);
is = s.accept().getInputStream();
System.out.println("accepted client");
dis = new DataInputStream(is);
try
{
byte input = dis.readByte();
System.out.println("read: " + input);
} catch (Exception ex)
{
System.out.println("Exception");
dis.close();
is.close();
s.close();
}
} catch (IOException ex)
{
System.out.println("ioexception");
}
}
}
CLIENT:
public static void main(String[] args)
{
Socket s;
OutputStream os;
try
{
s = new Socket("localhost", 4448);
s.setKeepAlive(true);
s.setReuseAddress(true);
os = s.getOutputStream();
int counter = 0;
while (true)
{
try
{
os.write((byte) counter++);
os.flush();
os.close();
s.close();
s = new Socket("localhost", 4448);
s.setKeepAlive(true);
s.setReuseAddress(true);
os = s.getOutputStream();
} catch (Exception e)
{
e.printStackTrace();
System.err.println("ERROR: reconnecting...");
}
}
} catch (Exception ex)
{
ex.printStackTrace();
System.err.println("ERROR: could not connect");
}
}
Does anyone know how to properly reconnect?
Don't close the ServerSocket on an error, just .accept() a new connection.
What I normally do is each time ServerSocket.accept() returns a Socket, I spawn off a thread to handle sending and receiving from that Socket. That way you're ready to start accepting a new connection as soon as somebody wants to connect to you.