IOException error when creating a socket in java - java

I am working on a chat client and I have created a registration Jframe where a user gets to register.
when registering, it is supposed to connect to server so that server can check if the userid already exists or not.
when I am creating a new socket it keeps giving me an error.
the code for the socket creation is:
try
{
String serverIP;
int Port = 5000;
Socket socks;
serverIP = String.valueOf(InetAddress.getLocalHost());
socks = new Socket(serverIP, Port);
InputStreamReader streamreader = new InputStreamReader(socks.getInputStream());
reader = new BufferedReader(streamreader);
writer = new PrintWriter(socks.getOutputStream());
writer.println(inputUsername + ":"+inputPassword+":"+inputConfirmPassword+":Register");
writer.flush(); // flushes the buffer
}
catch(IOException io)
{
System.err.println(io.getMessage()+"---connection error 1");
}
catch(SecurityException se)
{
System.err.println(se.getMessage()+"---connection error 2");
}
catch(IllegalArgumentException ae)
{
System.err.println(ae.getMessage()+"---connection error 3");
}
catch(NullPointerException ne)
{
System.err.println(ne.getMessage()+"---connection error 4");
}
when I execute, i get the following error:
Dell/172.16.3.24---connection error 1
this is generated by the IOException catch statement.
Can anyone tell me why this is happening and also how to rectify it?
thanks a lot.

IOException definition from javadoc
Signals that an I/O exception of some sort has occurred. This class is the general class of exceptions produced by failed or interrupted I/O operations.
While I don't have access to your full stacktrace, the statement Dell/127.16.3.24 let me believe that this is the IP address that was given when creating the socket.
I think you might want to try using InetAddress.getLocalHost().getHostAddress which will return only the IP while InetAddress.getLocalHost() will also return the hostname of the system.
InetAddress.getLocalHost from javadoc
Returns the address of the local host. This is achieved by retrieving
the name of the host from the system, then resolving that name into an
InetAddress.
Note that if you already know that you want local host ip, you can simply pass "127.0.0.1" when creating the socket and it should also fix the problem.
You should also consider adding the flush statement in a finally block to make sure the stream is flushed even if exception occurs. And for sure add a close statement in that block too.

Related

java tcp server to many connections

I wrote a simple TCP server to transfare some user Data to it and save it in an simple MySQL table. If i now run more than 2000 clients after each other it stops working. While running i get some IO error java.io.EOFException you may also see the misstake i made for that. But the most importand is that i get this
IO error java.net.SocketException: Connection reset
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Unknown Source)
at Server.main(Server.java:49)
Enough Memory schould be there but the threads are still running and i dont see where i made the misstake that they dont get terminated. So i got up to 3900 threads running than.
So here is the part of the Server:
try {
// create new socket
ServerSocket sock = new ServerSocket(port);
textArea.setText(textArea.getText() + "Server started\n");
while (true) {
// accept the connection
Socket newsock = sock.accept();
// handle the action
Thread t = new ThreadHandler(newsock);
newsock.setSoTimeout(2000); // adding client timeout
t.start();
}
} catch (Exception e) {
guess really simple. Here is how i handle the socket:
class ThreadHandler extends Thread {
private Socket socket;
private MySQLConnection sqlConnection;
ThreadHandler(Socket s) {
socket = s;
sqlConnection = new MySQLConnection();
}
public void run() {
try {
DataOutputStream out = new DataOutputStream(
socket.getOutputStream());
DataInputStream in = new DataInputStream(new BufferedInputStream(
socket.getInputStream()));
Server.textArea.append((new Date()) + "\nClient connected IP: " + socket.getInetAddress().toString()+"\n");
int firstLine = in.readInt(); // get first line for switch
switch (firstLine) {
case 0:
// getting the whole objekt for the database in own lines!
String name2 = in.readUTF();
int level2 = in.readInt();
int kp2 = in.readInt();
String skill = in.readUTF();
LeadboardElement element2 = new LeadboardElement();
element2.setName(name2);
element2.setLevel(level2);
element2.setKillPoints(kp2);
element2.setSkill(skill);
sqlConnection.saveChaToLeadboard(element2);
break;
//case 1 return the top10
###.... shorten here the rest of the cases
out.close();
in.close();
//close this socket
socket.close();
Server.textArea.append("Client disconnected IP: " + socket.getInetAddress().toString()+ "\n" + (new Date())
+ "\n----------------------------------------------------\n");
// autoscrolldown
Server.textArea.setCaretPosition(Server.textArea.getDocument()
.getLength());
} catch (Exception e) {
System.out.println("IO error " + e);
try {
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}finally{
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
the saveChaToLeadboard simply gets the name level kp and skill and uses a preparedStatement so save it to my MySQL Table.
I hope you can help me i just dont see the misstake of it. I think i need to Join it somewhere but if i put a join at the end of it (after socket.close()) it still does the same.
Here the save to database methode:
public void saveChaToLeadboard(LeadboardElement element) {
try {
// load driver
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(this.databaseURL
+ DATABASE_NAME, this.user, this.password);
// insert values into the prep statement
preparedStatement = connection
.prepareStatement(PREP_INSERT_STATEMENT);
preparedStatement.setString(1, element.getName());
preparedStatement.setInt(2, element.getLevel());
preparedStatement.setInt(3, element.getKillPoints());
if(!element.getSkill().equalsIgnoreCase("")){
preparedStatement.setString(4, element.getSkill());
}else{
preparedStatement.setString(4, null);
}
// execute
preparedStatement.executeUpdate();
connection.close();
} catch (Exception e) {
Server.textArea.append(e.getMessage() + "\n");
Server.textArea.setCaretPosition(Server.textArea.getDocument()
.getLength());
try {
connection.close();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
Thanks alot!
Regards
Your run() method is mangled, but I suspect that part of the problem is that you are not always closing network sockets and streams. In particular, I suspect that you are not closing them if there is an exception while reading, or processing the data you read. You should always close sockets and streams in a finally block (or the Java 7 equivalent).
Another potential problem is that some of the connections may be stalling due to the other end not sending data. To deal with that, you would need to set a read timeout on the socket ... so that connections to slow / stuck clients can be closed.
Finally, it is probably unrealistic to even try to process 2000+ connections in parallel with a thread per connection. That's a LOT of resources1. I recommend you use a thread pool with a fixed upper limit in the low hundreds, and stop accepting new connections if all threads are in use.
1 - Each thread stack occupies at least 64K of memory on a HotSpot JVM, and possibly as much of 1Mb. Then there are the Heap resources that the thread directly or indirectly refers to, and OS resources needed to maintain the state of the threads and the sockets. For 2000 threads, that's probably multiple Gb of memory.
IMHO 2000 threads is on the high side for a single process and 2000 database connections definately is.
Regardless of whether or not you're hitting limits with 2000 incoming connections, your approach simply will not scale.
To acheive scalability you need to look at using resource pools - this means:
a pool of reader threads reading from the sockets queuing the data for processing.
a pool of worker threads processing the data queued by the reader threads.
a pool of database connections used by the worker threads - this connection pool could be adjusted so that each worker thread has it's own connection but the important thing is that you don't continually open and close database connections.
Look at the concurreny API for the thread pools and the NIO API for the IO.
This arrangement will allow you to tune your server to acheive the desired throughput.

java ServerSocket does not throw IOException when bind to the same port

I have an issue with my code as follow.
code:
int port = 14205; // begin port
// Try to bind socket on any port<br>
while(true){
try {
InetSocketAddress isa = new InetSocketAddress(port);
Log.logFile("bind port = " + port);
// ss is a ServerSocket object
ss.bind( isa );
break;
} catch (IOException e) {
Log.logFile("exception");
port++;
}
}
I ran this code on JVM 1.7 and JVM 1.6 at the same time on the same machine (win7x64). using CurrPorts tool to investigate what port we are listening.
result: we'are listening on the same port 14207.
I think JVM must throw an IOException when run 2nd instance of this code but it didn't.
what wrong with my code?
please help.
note: I must run in this senario (2 JVMs).
break; will break your while loop and exit from the while loop and no question about catching exception. However, When your are trying to catch the exception you need to print exception message to log file.
replace this
Log.logFile("exception");
with this
Log.logFile("exception"+ e.toString());
Your loop breaks after binding first time.
ok! I will answer my question.
this is JVM bug. for more information please refer to Oracle bugbase:
http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=71f70e71266a551ce53dcda4a050c?bug_id=7174699

Java: Using variables from try blocks

So I've got a thing like this:
try{ServerSocket acceptor = new ServerSocket(4782);}
catch(IOException e){System.err.println("ERROR: Couldn't listen on port 4782!");}
while (true)
{
Socket clientSock = acceptor.accept();
}
But when trying to assign clientSock, it says it can't find acceptor. When moving the acceptor out of the try block, it explodes with an unhandled exception.
Should I be putting a thing like Socket clientSock; before the try block?
Thanks.
An alternative to what the other folks here have suggested: you could move more code into the try block:
try{
ServerSocket acceptor = new ServerSocket(4782);
while (true) {
Socket clientSock = acceptor.accept();
}
} catch(IOException e){
System.err.println("ERROR: Network problem:" + e.getMessage());
}
The advantage of doing things this way -- when you can get away with it -- is that the "happy path" reads more clearly; it's easier to follow what the code is supposed to do. The dark side of this approach is that it leads to lumping various error conditions together, so you can't react as specifically to individual problems. Sometimes, though, even that is an advantage rather than a problem.
You can keep the instantiation in the try-catch but move the variable declaration out.
ServerSocket acceptor = null;
try{acceptor = new ServerSocket(4782);}
catch(IOException e){System.err.println("ERROR: Couldn't listen on port 4782!");}
while (true)
{
Socket clientSock = acceptor.accept();
}
No you should put the declarion of acceptor before the try block, like this:
ServerSocket acceptor = null;
try {
acceptor = new ServerSocket(4782);
} catch (IOException e) {
System.err.println("ERROR: Couldn't listen on port 4782!");
}
while (true) {
Socket clientSock = acceptor.accept();
}
For this code, acceptor can be null inside the while-loop, either check for it there or do something flow-alterning inside the catch-block.
You might also want to handle the IOException that Socket clientSock = acceptor.accept();
might throw, since such Exception would break the while-loop - which might not be according to plans.
The general explaination is that java scopes variable declarations "as limiting as possible" acceptor was declared inside the try-block in your code, hence not available/undeclared outside of it.

Java Exception - Socket is closed, reliable udp help?

I'm currently using a Java implementation of the Reliable UDP protocol, found [here][1]. The project has absolutely no tutorials so I have found it really hard to identify problems.
I have set up a client and server. The server runs on localhost:1234 and the client runs on localhost:1235. The server is first established, and loops listening for connections.
I then have set it to send a packet to the server. When a packet is sent, the server calls handlePacket() -
DataInputStream i = new DataInputStream(client.getSocket().getInputStream());
short packetID = i.readShort();
i = null;
switch(packetID){
case 3:
Packeta packeta = new Packeta(client);
break;
}
} catch (IOException e) {
e.printStackTrace();
}
I'm currently using a debugging with a small dummy class called Packeta. When the constructor is called, it reads from a stream and the logs to the console. However, always when constructing, it hangs for 10 seconds, before producing the error -
java.net.SocketException: Socket is closed ....
at
lessur.engine.net.packets.Packeta.(Packeta.java:15)
The constructor for Packeta -
public Packeta(LessurConnectedNode c) {
super((short)3, c);
try {
/*LINE 15*/ Logger.getLogger("adsfas").info("X was "+c.getSocket().getInputStream().read());
} catch (IOException e) {
e.printStackTrace();
}
}
It has something todo with the input streams. I don't know what is wrong, but from reading other threads, it might be todo with having multiple inputstreams. I'm lost on this, please help.
The problem was, I was passing the server to the socket listener, before the socket was fully initialized. FIXED!

Java ObjectInputStream hanging

I am feeling really stupid right now guys.... basically I am connecting over TCP on a local machine... and when I try to make the In/out streams at the client it wont get passed creating the object input stream. What gives? This stops after printing 2... no exceptions or anything... This isn't the first time I've used this class which is partialy why I am puzzled.
try {
System.out.println("1");
mySocket = new Socket("localhost", 11311);
System.out.println("12");
oos = new ObjectOutputStream(mySocket.getOutputStream());
System.out.println("2");
ois = new ObjectInputStream(mySocket.getInputStream());
System.out.println("13");
} catch (Exception e) {
e.printStackTrace();
}
From the specification of ObjectInputStream:
This constructor will block until the corresponding ObjectOutputStream
has written and flushed the header.
(For future readers:) I had the same problem because i made a silly change in server program and didn't test it for a long time then i was confused about why program is locked.
ServerSocket accepts the connection (responderSocket = serverSock.accept();) then suddenly for a inapropriate if (The silly change i mentioned!) program jumps out of the thread and because i didn't add a finally block to close streams and sockets the socket was left abandoned w/o sending or recieving anything (even stream headers). So in client side program there was no stream header (When i debbugged The code i saw that the last function executed before lock was:
public ObjectInputStream(InputStream in) throws IOException {
verifySubclass();
bin = new BlockDataInputStream(in);
handles = new HandleTable(10);
vlist = new ValidationList();
enableOverride = false;
readStreamHeader(); //// <== This function
bin.setBlockDataMode(true);
}
readStreamHeader();)
So be careful about what happens in server side, maybe problem isn't where you expecting it!

Categories