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.
Related
This is the server side code
I'm pretty sure the error is that the Server Socket Isn't closing the port?
There is no problem when I run the program but, When I run it again I get this Error:
Exception in thread "main" java.net.BindException: Address already in use: bind
at java.base/sun.nio.ch.Net.bind0(Native Method)
at java.base/sun.nio.ch.Net.bind(Net.java:550)
at java.base/sun.nio.ch.Net.bind(Net.java:539)
at java.base/sun.nio.ch.NioSocketImpl.bind(NioSocketImpl.java:643)
at java.base/java.net.ServerSocket.bind(ServerSocket.java:396)
at java.base/java.net.ServerSocket.<init>(ServerSocket.java:282)
at java.base/java.net.ServerSocket.<init>(ServerSocket.java:173)
at internet.server.main(server.java:11)
But if I change the port number it fixes for that one time running. Someone please help also I haven't learned java server sockets or client sockets yet soo I need help as far as I know no one else is having this problem
package internet;
import java.io.IOException;
import java.net.*;
import java.io.*;
public class server {
public static void main(String[] args) throws IOException {
println("Compiled");
ServerSocket ss = new ServerSocket(5502);
Socket s = ss.accept();
println("Client Connected!");
InputStreamReader in = new InputStreamReader(s.getInputStream());
BufferedReader bf = new BufferedReader(in);
String str = bf.readLine();
println("Client: " + str);
s.close();
ss.close();
}
public static void println(String args) {
System.out.println(args);
}
}
This will works fine as long as you terminate your previous execution before you re run it.
Try closing those streams, InputStreamReader and BufferedReader as well. Close them before socket and ServerSocket.
bf.close();
in.close();
I wrote a basic code in which sender is sending a message to the receiver and the receiver is printing it. I am a naive socket programmer. I looked into various post but still not able to resolve this issue.
Here is my code:
TCPServer.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.net.*;
import java.io.*;
import java.util.*;
import org.omg.CORBA.Any;
public class TCPServer {
public static void main(String args[]) throws IOException{
TCPServer tcpServer=new TCPServer();
ServerSocket serverSocket=new ServerSocket(8777);
Socket sock=serverSocket.accept();
BufferedReader inputSenderBuffer=new BufferedReader(new InputStreamReader(sock.getInputStream()));
DataOutputStream outputToSenderBuffer=new DataOutputStream(sock.getOutputStream());
outputToSenderBuffer.flush();
//outputToSenderBuffer.close();
char[] inputArray=new char[2000];
int i,lengthMessage;
int a=1;
System.out.println("We are here");
while(a<1000)
{
System.out.println("Inside this while loop");
String inputSender=inputSenderBuffer.readLine();
lengthMessage=inputSender.length();
for(i=0;i<lengthMessage;i++)
{
System.out.println("putting the received message into buffer");
inputArray[i]=inputSender.charAt(i);
System.out.println(inputArray[i]);
}
}
}
}
TCPClient.java
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.*;
public class TCPClient {
public static void main(String args[])
{
try {
Socket sock=new Socket("localhost",8777);
DataOutputStream outputToReceiverBuffer=new DataOutputStream(sock.getOutputStream());
System.out.println("Sending test message");
int i=1000;
while(i<1000)
{
outputToReceiverBuffer.writeBytes("1AAAAAAAAAA");
outputToReceiverBuffer.flush();
//outputToReceiverBuffer.close();
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Exception at the TCPServer.java console
Exception in thread "main" 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 TCPServer.main(TCPServer.java:31)
Kindly help me resolving this.
You're not writing anything:
int i=1000;
while(i<1000)
and you're never closing the socket. So when the sender exits, the connection is reset, et voila.
When you fix that, you're reading lines:
String inputSender=inputSenderBuffer.readLine();
but you're not writing lines:
outputToReceiverBuffer.writeBytes("1AAAAAAAAAA");
outputToReceiverBuffer.flush();
Instead of using DataOutputStream.writeBytes() you should use BufferedWriter.write()/newLine().
You're also not checking the result of readLine() for null, which indicates that the peer has closed the connection, so you should stop reading and close your socket. You should rely on that rather than an arbitrary counter to control your read loop.
I'm trying to play around with the concurrent package and for this reason I tried to write a simple socket handler. Here is the code:
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MultiThreadedServer{
private final static int number_of_threads = 4;
private final static int port = 1134;
public static void main(String[] args){
try{
ServerSocket ss = new ServerSocket(port);
ExecutorService pool = Executors.newFixedThreadPool(number_of_threads);
for(;;){
pool.execute(new SocketHandler(ss.accept()));
}
}catch(Exception e){
System.out.println(e.toString());
}
}
}
class SocketHandler implements Runnable {
private Socket socket;
SocketHandler(Socket s){
this.socket = s;
System.out.println("-- Socket has connected -- ");
}
public void run(){
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String s = "";
while((s = reader.readLine()) != null ){
System.out.println(s);
}
}catch(Exception e){
System.out.println(e.toString());
}
}
}
This code ^^ simply waits for sockets and reads whatever the socket sends. It works fine to an extent. ( I will explain a bit later what bothers me).
The following code is the sender class which "sends" a socket
import java.io.*;
import java.net.*;
public class Sender{
public static void main(String args[]){
try{
int port = Integer.parseInt(args[0]);
Socket socket = new Socket(InetAddress.getByName(null),port);
PrintWriter writer = new PrintWriter(socket.getOutputStream());
writer.write("Wohoo!");
writer.close();
}catch(Exception e){
System.out.println(e.toString());
}
}
}
The code compiles fine and it even runs fine when I run my sender. However if I type
java Sender
about 3 times a second and I try to run it into my console the following thing gets printed:
java.net.BindException: Address already in use
However the whole point of this code was to not block the connections to my port and to queue the tasks. How can I tackle this?
See my comment. But I think what you are seeing is exhausting your tcp ports. Are you running this thing for awhile before it starts printing port already in use? If so read ahead.
So after closing a socket there is a state of TIME_WAIT. Until it passes, you cannot reuse same port unless you have set the socket option SO_REUSEADDR.
So you need to use that option perhaps. See this answer for more insight:
https://stackoverflow.com/a/14388707/520567
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();
}
}
I can't understand why the code below doesn't work. The client sends a message to the server, and the server prints the message to standard output.
Code for the server:
import java.net.*;
import java.io.*;
import java.math.BigInteger;
public class server
{
public static void main(String args[])
{
try
{
ServerSocket server = new ServerSocket(8080);
while (true)
{
// initializations
Socket connection = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
PrintWriter out = new PrintWriter(connection.getOutputStream());
// listen for client message
String message = in.readLine();
// print raw message from client
System.out.println(message);
// close resources
if (out != null)
out.close();
if (in != null)
in.close();
if (connection != null)
connection.close();
}
}
catch (Exception e)
{
System.out.println(e.getMessage());
System.exit(1);
}
}
}
Code for the client:
import java.net.*;
import java.io.*;
import java.math.BigInteger;
public class client
{
public static void main(String args[])
{
try
{
// initializations
Socket connection = new Socket("localhost", 8080);
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
PrintWriter out = new PrintWriter(connection.getOutputStream());
// send message to server
out.println("Hello, world!");
// close resources
if (in != null)
in.close();
if (out != null)
out.close();
if (connection != null)
connection.close();
}
catch (Exception e)
{
System.out.println(e.getMessage());
System.exit(1);
}
}
}
Any insights? Thanks!
What you should be doing to figure out this type of problem, is to isolate where the problem comes from. Is it the Server portion, or the client portion? An easy test for the server is to start it up, then telnet to that port (ex. "telnet 127.0.0.1 8080") type in something and see if it is outputing. (btw, your server code works fine).
Doing this would allow you to focus on your client code. As Affe stated, you simply didn't flush out the input stream. Learning methodologies for troubleshooting code is at least as important as learning to write code.
Also as an aside, by convention, Java classes start with a capital letter, so it should be "Server" and "Client"
That default PrintWriter does not autoflush. (and doesnot flush on close as abstract Writer deceptively may lead you to believe. Either do:
PrintWriter out = new PrintWriter(connection.getOutputStream(), true);
or else
out.println("Hello, world!");
out.flush();
Add a flush after you write to the stream in your client :
// send message to server
out.println("Hello, world!");
out.flush();
Also Make sure the server socket is not blocked by firewall