Equivalent Java functions to C functions in network programming - java

I'm doing a comparison between some C functions used in network programming, and their Java counterpart. Most of them I can find in documents about Socket, ServerSocket, InetAddress classes.
However I can't seem to find listen(), recv(), send() and getaddrinfo() in Java. As far as I go, I see that most Java client-server programs do not require them, as you can just write the byte/message and flush them directly to the other end, using flush() or PrintWriter().
Do I understand this right, and are there any equivalent functions to those three?

When you create a ServerSocket, the underlying listen function gets called when you bind to a port, either through the constructor or though the bind method.
The recv and send functions are called by reading from and writing to the InputStream and OutputStream respectively that are attached to a Socket instance and returned by the getInputStream and getOutputStream methods.

Listening and receiving can be implemented in multiple different ways. Java is object-oriented so the logic is usually represented by a specific object type.
Take a look at Reading from and Writing to a Socket tutorial which gives a few examples on working with sockets, e.g. using InputStream and OutputStream to interact with Socket:
try (
Socket echoSocket = new Socket(hostName, portNumber);
PrintWriter out =
new PrintWriter(echoSocket.getOutputStream(), true);
BufferedReader in =
new BufferedReader(
new InputStreamReader(echoSocket.getInputStream()));
BufferedReader stdIn =
new BufferedReader(
new InputStreamReader(System.in))
)

Related

How can I send multiple objects over one socket in java?

When I send only one object through a socket i am ok. But when i am trying to send two objects, i get
Exception in thread "main" java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source))
I have tried almost everything like flush() or reset() but none of them work.
public String SendObject(Object o) throws IOException {
OutputStream outToServer = client.getOutputStream();
ObjectOutputStream out = new ObjectOutputStream(outToServer);
out.writeUnshared(o);
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
return in.readUTF();
}
You're using an ObjectOutputStream to write the Object(s) from the client. You should be using an ObjectInputStream (not a DataInputStream) to read them on the server. To read two Objects might look something like,
InputStream inFromServer = client.getInputStream();
ObjectInputStream in = new ObjectInputStream(inFromServer);
Object obj1 = in.readObject();
Object obj2 = in.readObject();
Also, on the client, I think you wanted writeObject (instead of writeUnshared) like
ObjectOutputStream out = new ObjectOutputStream(outToServer);
out.writeObject(o);
While the other answers (e.g. #EJP's) are correct about the right way to send / receive objects and handle the streams, I think that the immediate problem is on the server side:
Exception in thread "main" java.net.SocketException: Connection reset
This seems to be saying that the connection has broken before the client receives a response. When the client side attempts to read, it sees the broken (reset) connection and throws the exception.
If (as you say) the sendObject method works first time, then I suspect that the server side is closing its output stream to "flush" the response ... or something like that.
You must use the same streams for the life of the socket, not new ones per send (or receive).
You need to decide between Object streams and Data streams. Don't mix them.
Don't try to mix between writeObject()/writeUnshared() and readUTF().

java - continuous data sending through Socket

I'm writing a Java client/server application. It should allow clients to send text data to the server. This kind of communication should be repeatable many times using the same connection.
I write it like this:
// On a server:
ServerSocket serverSocket = new ServerSocket(port);
Socket socket = serverSocket.accept();
socket.setKeepAlive(true);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
if (reader.ready()) {
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
// do something with line
}
}
// On a client:
Socket socket = new Socket(host, port);
socket.setKeepAlive(true);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.write("Some data from client to server");
writer.flush();
The problem is: I can't read on a server before I close OutputStream on a client. Or I can't open OutputStream on a client again, if it was already closed. How can I do continuous sending and reading of data?
You need two threads at both ends, one for reading data and other one for writing data.
The problem is: I can't read on a server before I close OutputStream on a client.
Yes you can. You just can't get to the case where readLine() returns null. It isn't the same thing.
Or I can't open OutputStream on a client again, if it was already closed.
Of course not. You have to create a new Socket.
How can I do continuous sending and receiving of data?
I don't understand the question. The code you posted doesn't attempt that.
If your goal is to send many mesages over the same socket connection, these messages will have to be delimited by an application-level protocol. In other words, you won't be able to rely on any system calls like reader.ready() or reader.readLine() == null to detect the end of the message on te server.
One way to achieve this is to begin each message with its length in characters. The server will then read exactly that number of charecters, and then stop and wait for a new message. Another is to define a special character sequence which concludes each message. The server will react to reading that particular sequence by ending the reading of the current message and returning to the "wait for new message" state. You must ensure that this sequence never appears in the message itself.

Redirect InputStream to SocketĀ“s OutputStream

Suppose I have following Java code on a server:
Socket aSocket = new Socket(aInetaddr, aPort); //aSocket is a client i m connecting to
InputStream input = aSocket.getInputStream();
Socket bSocket = new Socket(bInetaddr, bPort); //bSocket is a client i m connectin to
Now what I would like to achieve is, to pass the InputStream "input" from the aSocket to the bSocket. I have no information about whats coming from the InputStream, or how it is used in the end.
The whole transfer of data has to pass my server, I can't make a direct connection between the 2 clients.
Get the output stream for the second socket and then you can do this trivially using Apache Commons IOUtils.copy(). Amongst many variants there's one that takes an input and output stream as arguments.

PrintWriter sends and DataInputStream reads it

I got server-client application. On the client side, I am using this I/O stream to output data:
out = new PrintWriter(socket.getOutputStream(), true);
out.println("yeah");
On the server side I am trying to read the product by this line:
DataInputStream din = new DataInputStream(s.getInputStream());
String clientId = din.readUTF();
The server reaches the above statement and stops there. What's the problem? Are the two I/O streams not compatible with each other?
There are no exceptions thrown by either party, no output. I simply added System.out.println() before and after the above statement I=and I determined that the program does not cross this line:String clientId = din.readUTF();
You should use the DataOutputStream.writeUTF() method if you want to read from the other end of the socket with DataInputStream.readUTF(). See the Javadoc on DataInput for more detail on why. As an alternative, try using a buffered reader or scanner to read in your data.

What is the best way to code a Java TCP client (C# server)?

I have a server written in C# and need to talk to it from Java 1.6. I need to connect to the server, maintain the connection, and send messages in both directions. The messages are an int (length of the message) and then an XML file.
What is the best way to do this? I know Java well but I've never done TCP from Java (have done it from C#). So I have no idea what the best way to do this is. Speed is not an issue and simplicity is useful.
thanks - dave
So you want to build a Java client using Socket API. It's pretty simple to do.
try {
Socket socket = new Socket( host, port );
BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream() ) );
PrintWriter out = new PrintWriter( new OutputStreamWriter( socket.getOutputStream() ) );
out.println("HELO");
String response = in.readLine();
System.out.println( response );
} finally {
in.close();
out.close();
socket.close();
}
Since you're only exchanging integers, you might want to use the classes Socket and DataOutputStream (for sending) and DataInputStream (for receiving).
I highly recommend to make the use of threads.
For starters, check out this tiny demo.
From there, the helpers provided by Apache Commons Net may clean up some of the lower-level work.

Categories