As I mentioned in this question, I was getting a SocketException: Connection reset.
After implemented Aaron's answer it seems to be working as intended. But today that I run the code again, I got once again the connection reset error.
The problem is that if I run my code like 5 times, it seems to work 2/5 times and the rest gives me the error...
Server:
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ServerSocket server = new ServerSocket(444);
while (true) {
Socket socket = server.accept();
ObjectInputStream objIn = new ObjectInputStream(socket.getInputStream());
Object objRead = objIn.readObject();
if (objRead != null) {
System.out.println(objRead);
}
}
}
}
Client:
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.util.HashMap;
public class Client {
public static void main(String[] args) throws IOException {
Socket sock;
int port = 444;
HashMap<Integer, String> mapSend= new HashMap<>();
mapSend.put(1,"row1");
mapSend.put(2,"row2");
sock = new Socket(InetAddress.getLocalHost(), port);
ObjectOutputStream objOut = new ObjectOutputStream(sock.getOutputStream());
objOut.writeObject(mapSend);
objOut.flush();
}
}
This is the error: (it appears on the output of the server, after I run the client):
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:189)
at java.net.SocketInputStream.read(SocketInputStream.java:121)
at java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2308)
at java.io.ObjectInputStream$BlockDataInputStream.read(ObjectInputStream.java:2716)
at java.io.ObjectInputStream$BlockDataInputStream.readFully(ObjectInputStream.java:2740)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1978)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1913)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1796)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at java.util.HashMap.readObject(HashMap.java:1154)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1891)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1796)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at iotest.Server.main(Server.java:16)
On the client side I get no errors.
EDIT
Any way I can debug the client-server? That might help out to give you guys more info on this.
Close the output stream, instead of just flushing it.
NB readObject() doesn't return null unless you write null. The test is pointless.
Related
This question already has an answer here:
Address reuse not working on new Java Runtime Environment
(1 answer)
Closed 5 years ago.
Maybe I misunderstand the use of this code, but from what I understand, calling setReuseAddress(true) will allow the port to be used even if the computer still thinks it is in use.
Scenario: I have the below code. When it crashes it does not close the port, so it throws a bind error on next launch. I have used setReuseAddress(true) to try to force it to open the port, but it throws the same error. If this is the right code, how do I use it? If it's the wrong code, what will allow this behavior?
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
public class ServerPsswd {
public static void main(String[] args) throws IOException {
ServerSocket listener = new ServerSocket();
listener.setReuseAddress(true);
listener.bind(new InetSocketAddress(9090));
try {
while (true) {
Socket socket = listener.accept();
try {
PrintWriter out =
new PrintWriter(socket.getOutputStream(), true);
out.println("tada!");
out.println("yays");
} finally {
socket.close();
}
}
}
finally {
listener.close();
}
}
}
https://docs.oracle.com/javase/7/docs/api/java/net/Socket.html#setReuseAddress(boolean)
It is to allow connections during the timeout period AFTER the current connection has been closed
I have created a simple class which sends a string to a server, both communicate using Java Sockets API. The server reads what the client have sent, and responds with another string. But the client can not read that response.
This is the client class:
import java.io.IOException;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 8181);
socket.getOutputStream().write("Hello".getBytes());
int read;
while ((read = socket.getInputStream().read()) > -1) {
System.out.print((char) read);
}
socket.close();
}
}
And this is the server class:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8181);
while (true) {
Socket socket = serverSocket.accept();
int read;
while ((read = socket.getInputStream().read()) > -1) {
System.out.print((char) read);
}
socket.getOutputStream().write("Hi!".getBytes());
}
}
}
I imagine that the problem may be in the client execution flow, because I don`t know how canI do it wait for a server response. In other words, how to implement a client able to read the server response?
You aren't closing the sockets.
The server is attempting to read until end of stream and then send a reply. End of stream only happens when the peer closes the connection, so it won't be possible to send a reply even after you fix (1). You need to read a message, whatever that means in your application protocol.
You need to flush or close the outputstream.
i want to know the functionality of sockets in java. when i am creating some http-server i can use some ready to use sockets for secure and non-secure communication between two parties. but i never installed tomcat to my project, so my question is: how can java create a tcp / ip connection without a web-server? Can someone post me some link to clear this question?
In my case i used this to create a SSLSocket:
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.net.ssl.SSLServerSocketFactory;
public class MainClass {
public static void main(String args[]) throws Exception {
SSLServerSocketFactory ssf = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
ServerSocket ss = ssf.createServerSocket(5432);
while (true) {
Socket s = ss.accept();
PrintStream out = new PrintStream(s.getOutputStream());
out.println("Hi");
out.close();
s.close();
}
}
}
Thank u a lot,
Mira
I am quite a newbie to Java. Please excuse me if you find this as a very basic question.There are many answers available already in stack overflow about this and I went through almost all the possible helps i can get in Stack overflow and also in some other forums. Unfortunately none of them helped me.
I have client/server program in which the client send a string to server and server just attaches another string to the string sent by client and sends it back to the client.
Server program looks like this.
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class server {
public static void main(String[] args) {
try
{
ServerSocket server = new ServerSocket(7300);
Socket s = server.accept();
DataInputStream inp = new DataInputStream(s.getInputStream());
DataOutputStream out = new DataOutputStream(s.getOutputStream());
String str =inp.readUTF();
str = str+" buddy!";
out.writeUTF(str);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Client looks like This.
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.*;
public class client {
public static void main(String[] args) {
try
{
Socket s = new Socket("192.168.1.3",7300);
DataInputStream inp = new DataInputStream(s.getInputStream());
DataOutputStream out = new DataOutputStream(s.getOutputStream());
out.writeUTF("hi");
System.out.println(inp.readUTF());
Thread.sleep(2000);
out.writeUTF("hello");
System.out.println(inp.readUTF());
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Everything works fine while client writes "hi" and when client starts sending "hello" i am getting Connection reset error. I am not getting what mistake am i doing please help me in resolving this.
The output with the error i am getting looks like this.
hi buddy!
java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at java.io.DataOutputStream.write(Unknown Source)
at java.io.DataOutputStream.writeUTF(Unknown Source)
at java.io.DataOutputStream.writeUTF(Unknown Source)
at sokry.client.main(client.java:18)
In your server example, readUTF is only called once on the DataInputStream, even though the client wrote to the DataOutputStream twice. Thus, simply adding
str = inp.readUTF();
str = str + " buddy!";
out.writeUTF(str);
to your server example, after the last out.writeUTF(str), will solve your problem.
do comment on following line of your client.java file and try.it will work
Thread.sleep(2000);
`//out.writeUTF("hello");;
//System.out.println(inp.readUTF());
because when you are sending "hi" from client to server and server gives reply then it finished it work and it stop connection but in client.java you sending another request to server but server is at rest.
you should start server until client finish it work..
hope it will wait
I've been studying the book Pro Java 7 NIO.2 to get a better understanding of the NIO package, and wanted to work on some networking related code to better my understanding of how netty works in the background. The over-all error makes sense, but why the error is being thrown is beyond my comprehension.
java.lang.ClassCastException: sun.nio.ch.ServerSocketChannelImpl cannot be cast to java.nio.channels.SocketChannel
The first thing that I did was make sure that none of my code was importing anything from the sun packaging, and that everything was in-fact using the java.nio package. Everything seems to check out.
This error is thrown when I attempt to connect a client to the server, but what really bothers me is the general fact that it's trying to type-cast to a ServerSocketChannel and not just a SocketChannel, which leads me to believe that the Server is confused.
I do apologise in advance for a wall of code down below, but as everyone always requests that I post a running example I plan to do just that. This is three class files small.
TcpProcessor.java
package net.ogserver.proto.tcp;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import net.ogserver.proto.connections.Connection;
public class TcpProcessor implements Runnable {
public static int tcpPort;
public void run() {
try (Selector selector = Selector.open();
ServerSocketChannel serverSocket = ServerSocketChannel.open()) {
if((serverSocket.isOpen()) && (selector.isOpen())) {
serverSocket.configureBlocking(false);
serverSocket.bind(new InetSocketAddress(tcpPort));
serverSocket.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("Server has started and is waiting for connections...");
while(!Thread.interrupted()) {
selector.select();
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
while(keys.hasNext()) {
SelectionKey key = (SelectionKey) keys.next();
keys.remove();
if(!key.isValid()) {
continue;
}
if(key.isAcceptable()) {
processIncomingConnection(key, selector);
} else if(key.isReadable()) {
//processIncomingData(key);
} else if(key.isWritable()) {
//pushOutgoingData(key);
}
}
}
} else {
System.err.println("There was an issue constructing the socket.");
}
} catch(IOException e) {
e.printStackTrace();
}
}
private void processIncomingConnection(SelectionKey selectionKey, Selector selector) throws IOException {
ServerSocketChannel serverSocket = (ServerSocketChannel)selectionKey.channel();
SocketChannel clientSocket = serverSocket.accept();
clientSocket.configureBlocking(false);
System.out.println("Incoming connection from " + clientSocket.getRemoteAddress());
selectionKey.attach(new Connection(selectionKey));
clientSocket.register(selector, SelectionKey.OP_READ);
}
}
Connection.java
package net.ogserver.proto.connections;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
public class Connection {
private SelectionKey selectionKey;
private SocketChannel clientSocket;
private ByteBuffer networkInputBuffer;
private ByteBuffer networkOutputBuffer;
public Connection(SelectionKey selectionKey) {
this.selectionKey = selectionKey;
this.clientSocket = (SocketChannel)selectionKey.channel();
this.networkInputBuffer = ByteBuffer.allocate(1024);
this.networkOutputBuffer = ByteBuffer.allocate(8192);
}
public SelectionKey getSelectionKey() {
return selectionKey;
}
public ByteBuffer getInputBuffer() {
return networkInputBuffer;
}
public ByteBuffer getOutputBuffer() {
return networkOutputBuffer;
}
public SocketChannel getChannel() {
return clientSocket;
}
}
Server.java
package net.ogserver.proto;
import net.ogserver.proto.tcp.TcpProcessor;
public class Server {
private Thread tcpProcessor;
public Server(int port) {
TcpProcessor.tcpPort = port;
tcpProcessor = new Thread(new TcpProcessor());
tcpProcessor.start();
}
public static void main(String[] args) {
new Server(5055);
}
}
There error occurs when TcpProcessor#processIncomingConnection is called, which invokes the creation of a new Connection instance. The line throwing this error is a direct quote from the book, and I've taken a look at a few other NIO servers and the line is exactly the same (Minus some naming) in most of them.
this.clientSocket = (SocketChannel)selectionKey.channel();
Any help would be greatly appreciated, full console output for those who want it:
Server has started and is waiting for connections...
Incoming connection from /127.0.0.1:53221
Exception in thread "Thread-0" java.lang.ClassCastException: sun.nio.ch.ServerSocketChannelImpl cannot be cast to java.nio.channels.SocketChannel
at net.ogserver.proto.connections.Connection.<init>(Connection.java:17)
at net.ogserver.proto.tcp.TcpProcessor.processIncomingConnection(TcpProcessor.java:60)
at net.ogserver.proto.tcp.TcpProcessor.run(TcpProcessor.java:37)
at java.lang.Thread.run(Thread.java:745)
I should probably add that the implementation of typecasting socketchannel form the selectionkey.channel() comes straight from the JavaDocs -- http://www.onjava.com/pub/a/onjava/2002/09/04/nio.html?page=2
You're passing the wrong SelectionKey to new Connection(...). You're passing the server socket's key. The key you should pass is the accepted socket's key, which is the result of socketChannel.register(), on the next line.
The sun.nio.ch.* classes appear to contain some implementations of interfaces in the java.nio.* package(s); the crossover to the different package occurs in the implementation classes you're using. No great mystery there.
By looking at the source for sun.nio.ch.ServerSocketChannelImpl, I see that it implements java.nio.channels.ServerSocketChannel, not java.nio.channels.SocketChannel. It's a channel implementation, not a socket implementation. Both the ServerSocketChannel and SocketChannel (in java.nio.channels) extend AbstractSelectableChannel, but they are siblings in the inheritance hierarchy, not ancestor/descendant.
Hope that helps.