Java: Using variables from try blocks - java

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.

Related

Client side is not sending message to server Java Socket

I am learning about sockets in java, but when I was running a program that sends messages from the client side to server side it doesn't show a message. If I enter some text on the client side it doesn't show up on the server side, but if I type endProcess it stops running. Which means that the message is going through it's just not showing up.
My Client.java code is here:
import java.net.*;
import java.io.*;
public class Client{
Socket soc;
DataInputStream dis;
DataOutputStream dos;
public Client(){
try{
soc = new Socket("(Address)",5000);
System.out.println("Connection Established");
dis = new DataInputStream(System.in);
dos = new DataOutputStream(soc.getOutputStream());
System.out.println("Streams connected");
}catch(UnknownHostException u){
System.out.println(u);
}catch(IOException i){
System.out.println(i);
}
String line = "";
while(!line.equals("endConnection")){
try{
line = dis.readUTF();
dos.writeUTF(line);
}catch(IOException i){
System.out.println(i);
}
}
try {
soc.close();
dis.close();
dos.close();
} catch (Exception e) {
System.out.println(e)
}
}
public static void main(String[] args) {
new Client();
}
}
Here is my Server.java code:
import java.net.*;
import java.io.*;
public class Server {
ServerSocket serSoc;
Socket soc;
DataInputStream dis;
public Server(){
try {
serSoc = new ServerSocket(5000);
System.out.println("Server Online");
soc = serSoc.accept();
System.out.println("Client Connected");
dis = new DataInputStream(new BufferedInputStream(soc.getInputStream()));
String line = "";
System.out.println("Waiting for input...");
while(!line.equals("endConnection")){
line = dis.readUTF();
System.out.println(line);
}
System.out.println("Client disconnected");
soc.close();
dis.close();
} catch (Exception e) {
System.out.println(e);
}
}
public static void main(String[] args) {
new Server();
}
}
There are many problems here.
Duplex protocol issues
line = dis.readUTF();
dos.writeUTF(line);
This isn't going to work; The dis.readUTF() line is going to block (freeze) until a line is read. The problem is, sometimes you have nothing to send in which case you want to read, and something you have nothing to read in which case you want to send. In practice you need to redesign this entirely; you need 2 threads. At which point you get into the issues of multicore, needing synchronization primitives and/or java.util.concurrent classes for all data that is shared between the 2 threads.
Alternatively, adopt a model that is strictly push or pull (where at any given time both parties already know who can send, and if the other party wants to send they simply cannot. For example, every party sends a simply 'NOTHING TO DO' message every second, trading places every time. This is quite an inefficient algorithm, of course. But could be written without involving multiple threads.
Flush and close issues
dos.writeUTF(line);
This doesn't actually send anything, or at least, isn't guaranteed to. To send any data on the internet, it gets wrapped in a packet which has lots of overhead. So, things are buffered until there's a full packet to send. Which means that line doesn't do anything. It just fills a buffer, no packets go out. You first need to close or flush. dos.flush() would help maybe. This is a big problem, because later you do:
soc.close();
dis.close();
dos.close();
You first close the socket, which, well, closes the socket. You then close the streams, which will also send anything that's still stuck in a buffer, except, that will fail, because the socket is already closed. In other words, the line you .writeUTF()-ed? It never gets there. You first shove it in a buffer, then you close the socket, then you send the buffer which won't work as the socket is already closed.
Broken error handling
} catch (Exception e) {
System.out.println(e);
}
Horrible. Don't do this. Your code reacts to any problem by printing something and just keeping right on going. That means if anything goes wrong, the client will start spamming an endless cavalcade of exception traces and locking up the system with any luck. You want the code to stop running when problems occur. Easiest way, by far, is to just stick throws IOException on your constructor and main method, which is allowed. Distant second best option is to configure your 'eh whatever' catch blocks as throw new RuntimeException("unhandled", e); instead of e.printStackTrace().
What you do (System.out.println(e);) is even worse - you are tossing away extremely useful information such as the stack trace and causal chain.

How to catch a socket-timeout in Java

I'm writing a server with Java.net. Now i want to change some variables on socket-timeout.
I cant find a 'onTimeout' interface or something similar.
Now I'm searching for a solution for this problem.
You say you're using java.net so I'm assuming that you're using something like a java.net.ServerSocket. If you call setSoTimeout on your instance of ServerSocket, you will be able to set a timeout for your socket. Then, when you block during calls to accept, your ServerSocket will keep track of the timeout. As you can see in the documentation, accept throws a SocketTimeoutException if a timeout has been defined and the wait time has exceeded the timeout. So, you'll end up with something like this (forgive me for being a bit rusty on Sockets):
try(ServerSocket ssock = new ServerSocket(...))
{
ssock.setSoTimeout(10_000); // 10 second timeout
while(true)
{
Socket csock = ssock.accept();
methodToStartThreadThatHandlesClientSocket(csock);
}
}
catch(SocketTimeoutException ste)
{
//handle socket timeout
}
catch(Exception other)
{
//handle other exceptions
}

IOException error when creating a socket in 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.

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 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