I'm working on an assignment where I have to make 3 programs, a client, a proxy, and a server. The client is supposed to send messages to the server by sending them to the proxy, which sends them to the server, and vice versa. The server waits for the proxy to connect to it, and the proxy waits for the client to connect to it, then the client sends a message to the proxy which gets sent to the server. When I compile them though, while the proxy gets the message fine, the serve gets an error.
Exception in thread "main" java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:196)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:154)
at java.io.BufferedReader.readLine(BufferedReader.java:317)
at java.io.BufferedReader.readLine(BufferedReader.java:382)
at Server.run(Server.java:18)
at Server.main(Server.java:8)
Here is the client code
import java.net.*;
import java.io.*;
public class Client {
public static void main(String[] args) throws Exception{
Client serv = new Client();
serv.run();
}
public void run() throws Exception{
Socket sock = new Socket("localhost", 7777);
PrintStream ps = new PrintStream(sock.getOutputStream());
ps.println("Hello Server");
sock.close();
}
}
Here is the proxy,
import java.net.*;
import java.io.*;
public class Proxy {
public static void main (String[] args) throws Exception{
Proxy serv = new Proxy();
serv.run();
}
public void run() throws Exception{
ServerSocket ss = new ServerSocket(7777);
Socket sock = ss.accept();
InputStreamReader ir = new InputStreamReader(sock.getInputStream());
BufferedReader br = new BufferedReader(ir);
String message = "";
message = br.readLine();
System.out.println(message);
Socket sck = new Socket("localhost", 8888);
PrintStream ps = new PrintStream(sock.getOutputStream());
boolean waiting = true;
while(waiting){
if(message != null){
ps.println("Hey Server, Client says: " + message);
waiting = false;
}
}
sock.close();
}
}
and here is the server
import java.net.*;
import java.io.*;
public class Server {
public static void main (String[] args) throws Exception{
Server serv = new Server();
serv.run();
}
public void run() throws Exception{
ServerSocket ss = new ServerSocket(8888);
Socket sock = ss.accept();
InputStreamReader ir = new InputStreamReader(sock.getInputStream());
BufferedReader br = new BufferedReader(ir);
System.out.println(br.readLine());
sock.close();
ss.close();
}
}
Does anybody know what I'm doing wrong?
Look at your proxy. First the sock Socket represents the connection with the client, then the sck Socket represents the connection with the server. However, when you create your PrintStream ps to connect with the server, you are using sock.getOutputStream as opposed to sck.getOutputStream. You are telling it to send information back to the client, which does not have an open BufferedReader to interpret, nor an open Socket at that point. Attempting to write to a closed connection results in a connection reset exception.
Secondly (though this is not causing the error), your proxy while loop is all jacked up. If you examine it, it will obviously cycle through at least once because waiting is defaulted to true. Then, you are checking to see if message != null. In this case, message will never be null because the client is set to always send the same message, and only one message. Most importantly, however, if for whatever reason message was null, there is nothing in the while loop to change that -- it does not attempt to read the next value from br or anything, so you will simply be stuck in an infinite while loop.
I believe what you were looking for was this:
String message;
while((message = br.readLine()) != null){
ps.println("Hey server, Client says: " + message);
}
But as I said, a while loop is not necessary in this case because the client is set to send only one message anyways, so you can simply do this:
ps.println("Hey server, Client says: " + message);
... without any sort of looping.
Related
I created a simple server and a client, but the server could not read anything that was sent from the client. I also add a print statement after I sent the string, but it cannot be printed either.
public class Server {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ServerSocket serverSocket = new ServerSocket(6666);
Socket clientSocket = serverSocket.accept();
System.out.println("accepting client at address " + clientSocket.getRemoteSocketAddress());
ObjectInputStream in = new ObjectInputStream(clientSocket.getInputStream());
ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream());
String input = (String) in.readObject();
System.out.println(input);
out.writeObject("Received");
out.flush();
}
}
Below is the client, and I just want to send a string "?????does not send":
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Client client = new Client();
client.sentInfo();
}
private static class Client {
private ObjectInputStream objectInputStream;
private ObjectOutputStream objectOutputStream;
public Client() throws IOException {
Socket socket = new Socket("127.0.0.1", 6666);
this.objectInputStream = new ObjectInputStream(socket.getInputStream());
this.objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
}
public void sentInfo() throws IOException, ClassNotFoundException {
this.objectOutputStream.writeObject("?????does not send");
this.objectOutputStream.flush();
System.out.println("????????");
Message resp = (Message) this.objectInputStream.readObject();
System.out.println(resp.getMessage());
}
}
}
I tried something else, if I just use InputStream and use a buffer to read bytes, like this:
Server code
This is the client code: client code
The code in the two link above would work. However, it would not work if I tried to use ObjectInputStream:
This is the server: server
This is the client: client
This is the Message object I want to send: Message class
Can someone explain this for me please? Thanks!
To read Strings from a socket use something like this:
DataInputStream input = new DataInputStream(clientSocket.getInputStream());
String message = input.readUTF();
You can open multiple streams from a socket, so if you want to read something else that really needs the ObjectInputStream than it can be open as well. Don't forget to properly close the streams & sockets.
This is a simple java program that sends a string from client to server and the server returns the length of the string to the client.
First, I run my server, and then I run a client, type in a string but not pressing Enter, then I run the 2nd client, type in a string and press Enter. Then the second client doesn't get a response until the first client's Enter is pressed. How can I solve that problem?
TCP Client
public class TCPClient {
public static void main(String[] args) throws Exception {
String sentence;
String sentenceLength;
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket("mycomputer", 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');
sentenceLength = inFromServer.readLine();
System.out.println(sentenceLength);
clientSocket.close();
}
}
TCP Server
public class TCPServer {
public static void main(String[] args) throws Exception {
String clientSentence;
int clientSentenceLength;
ServerSocket welcomeSocket = new ServerSocket(6789);
while (true) {
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
clientSentenceLength = clientSentence.length();
outToClient.writeBytes(clientSentenceLength + "" + '\n');
}
}
}
As Martin Wickman has indicated in his comment, you need a separate thread. Here's what's happening.
Your server accepts a connection. It now won't do anything else until it has handled that connection.
So your client1 opens the connection to the server. This basically hogs the server (because the server isn't multithreaded or in any other way handling more than one client at a time). The server won't do anything else until it's done with client1.
To fix this, you need to create a thread to handle the client conversation. So your main loop accepts a fresh connection and feeds it to a brand new thread. That thread then handles that specific connection, and the main loop goes back to waiting for another client.
The server waits for the first client to send a sentence. This is the blocking line: clientSentence = inFromClient.readLine();
Only after the first client has send the message, the code will continue and only then the second client is actually handled by Socket connectionSocket = welcomeSocket.accept()
The way to solve is handle each client in its own thread. Simple raw untested example code:
public class ClientHandler implements Runnable {
private Socket socket;
public ClientHandler(Socket socket) {
this.socket = socket;
}
public void run() {
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(socket.getOutputStream());
clientSentence = inFromClient.readLine();
clientSentenceLength = clientSentence.length();
outToClient.writeBytes(clientSentenceLength + "" + '\n');
socket.close();
}
}
En then in the server, after you get the Socket from the accept() call you start a new Thread to handle the client:
while (true) {
Socket connectionSocket = welcomeSocket.accept();
new Thread(new ClientHandler(connectionSocket)).start();
}
I am having an issue figuring out how to keep a connection open with my server class. When it connects I want the client to send to the server that a client has connected, which it does. My issue is that right after it receives the message the java file stops running. Could anybody give me some advice on how to keep the Server waiting for a message from the user until a certain message is received? Thank you in advance, will be researching in the mean time.
Client class:
import java.io.*;
import java.net.*;
import java.util.*;
public class Client {
public static void main(String[] args) throws Exception
{
Client myClient = new Client();
myClient.run();
}
public void run() throws Exception
{
Socket clientSocket = new Socket("localhost", 9999);
PrintStream ps1 = new PrintStream(clientSocket.getOutputStream());
ps1.println("A client has successfully connected.");
//Sends message to the server
PrintStream ps = new PrintStream(clientSocket.getOutputStream());
Scanner scan = new Scanner(System.in);
String cMessage = scan.nextLine();
ps.println(cMessage);
//Reads and displays response from server
InputStreamReader ir = new InputStreamReader(clientSocket.getInputStream());
BufferedReader br = new BufferedReader(ir);
String message = br.readLine();
System.out.println(message);
}
}
Server class:
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws Exception
{
Server myServer = new Server();
myServer.run();
}
public void run() throws Exception
{
//Initializes the port the serverSocket will be on
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("The Server is waiting for a client on port 9999");
//Accepts the connection for the client socket
Socket socket = serverSocket.accept();
InputStreamReader ir = new InputStreamReader(socket.getInputStream());
BufferedReader br = new BufferedReader(ir);
String message = br.readLine();
//Confirms that the message was received
System.out.println(message);
if(message.equals("HELLO"))
{
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("Received our hello message.");
}
else
{
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("Did not receive your hello message");
}
}
}
use the while loop for continuouly running your server and compare the received message with the desired end message ( bye ) with the if condition, the code is given below,
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws Exception
{
Server myServer = new Server();
myServer.run();
}
public void run() throws Exception
{
//Initializes the port the serverSocket will be on
ServerSocket serverSocket = new ServerSocket(9999);
while(true)
{
System.out.println("The Server is waiting for a client on port 9999");
//Accepts the connection for the client socket
Socket socket = serverSocket.accept();
InputStreamReader ir = new InputStreamReader(socket.getInputStream());
BufferedReader br = new BufferedReader(ir);
String message = br.readLine();
//Confirms that the message was received
System.out.println(message);
if(message.equals("HELLO"))
{
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("Received our hello message.");
}
else
{
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("Did not receive your hello message");
}
}
if(message.equals("bye"))
break; // breaking the while loop.
} // end of while loop.
}
I have written a client-server TCP Socket program such that the client will enter a string and that will be displayed by the server(echo program)... the condition is when I enter bye the program should exit... Well and good the client program is exiting ... but the server program is exiting with a java.io.DataInputStream.readUTF() and readFully exceptions.. plz help me.. whats wrong in the code...
/*Client*/
import java.net.*;
import java.io.*;
public class echoclient {
public static void main(String args[]) throws Exception
{
Socket soc = new Socket("127.0.0.1",4000);
OutputStream sout = soc.getOutputStream();
DataOutputStream out = new DataOutputStream(sout);
DataInputStream din = new DataInputStream(System.in);
while(true)
{
String message = din.readLine();
if(message.equals("bye"))
break;
out.writeUTF(message);
}
soc.close();
}
}
/*Server*/
import java.io.*;
import java.net.*;
public class echoserver {
public static void main(String args[]) throws Exception
{
ServerSocket server = new ServerSocket(4000);
Socket soc = server.accept();
System.out.println("Server Started....");
InputStream sin = soc.getInputStream();
DataInputStream in = new DataInputStream(sin);
while(true)
{
String fromClient = in.readUTF();
if(fromClient.equals("bye"))
{break;}
System.out.println("Client says : "+fromClient);
}
soc.close();server.close();
}
}
Exception:
Exception in thread "main" java.io.EOFException
at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:340)
at java.io.DataInputStream.readUTF(DataInputStream.java:589)
at java.io.DataInputStream.readUTF(DataInputStream.java:564)
at echoserver.main(echoserver.java:15)
I think that the answer is that that's just what happens. The EOFException is the only way that the DataInputStream tell the caller that it has reached EOF. So if your server attempts to read when the socket has been closed by your client, that's what will happen.
There are two solutions:
Catch and handle the EOFException.
Modify your "protocol" so that the client (somehow) tells the server when it has sent the last message ... and is going to close the socket.
Closing the DataOutputStream on the client side is a good idea, but it probably won't solve the problem. A DataOutputStream is not buffered and neither is a Socket's OutputStream, so there should be no data to be flushed. (Any data outstanding data in the network protocol stack should be transmitted when the Socket or OutputStream is closed.)
I'm developing a game for a class that I am in, and it is about 99% done. However, I realized there is a problem: If the server and client disconnect, and the client attempts to reconnect (and the server is back up and running fine), the client is not making a new connection.
The server and client are both multi-threaded. If I send the client a Kick message, what happens is the client will close its socket. If I reconnect, I get a SocketException: socket closed even though whenever connect is pressed, a new Client is constructed, which is basically just a class that creates a socket and connects to the server with a get/send thread.
Do you think there is anything I am doing illogically? It is like it is attempting to use the old Socket and Client that were constructed, but if I do some println calls, I can see that it does construct a new one and they are in different memory locations.
Thanks!
After closing a socket, you cannot reuse it to share other data between Server and Client classes. From the Java Socket API, about close() method's description:
Any thread currently blocked in an I/O operation upon this socket will
throw a SocketException.
Once a socket has been closed, it is not available for further
networking use (i.e. can't be reconnected or rebound). A new socket
needs to be created.
Closing this socket will also close the socket's InputStream and
OutputStream.
If this socket has an associated channel then the channel is closed
as well.
Then, it isn't possible to close a socket and reopen it. That's the reason, I think, of the exception being thrown.
It can be easy! I made this program (server side):
import java.net.ServerSocket;
import java.net.Socket;
import java.io.DataInputStream;
import java.io.DataOutputStream;
public class Host{
public static void main(String[] args) throws Exception{
while(true){
ServerSocket ss = new ServerSocket(1300);
Socket s = ss.accept();
DataInputStream din = new DataInputStream(s.getInputStream());
String msgin = din.readUTF();
System.out.println(msgin);
ss.close();
s.close();
din.close();
}
}
}
Client side:
import java.net.Socket;
import java.io.DataInputStream;
import java.io.DataOutputStream;
public class Client{
public static void main(String[] args) throws Exception{
while(true){
Socket s = new Socket("localhost", 1300);
DataOutputStream dout = new DataOutputStream(s.getOutputStream());
dout.writeUTF("hello");
s.close();
dout.close();
}
}
}
It works, beacuse you can declare tons of Sockets with the same ServerSocket, so for example this works too:
ServerSocket ss = new ServerSocket(1300);
Socket a = ss.accept();
Socket b = ss.accept();
Socket c = ss.accept();
and you have 3 Sockets...
Remember: java waits for a client to connect when you declare a Socket!
Code:
Client:
import java.net.Socket;
public class client {
public static void main(String[] args) throws Exception{
Socket a = new Socket("localhost", 1300);
Thread.sleep(3000);
Socket b = new Socket("localhost", 1300);
Thread.sleep(3000);
Socket c = new Socket("localhost", 1300);
Thread.sleep(3000);
a.close();
b.close();
c.close();
}
}
Server:
import java.net.ServerSocket;
import java.net.Socket;
public class server {
public static void main(String[] args) throws Exception{
ServerSocket ss = new ServerSocket(1300);
System.err.println("Listening...");
Socket a = ss.accept();
System.err.println("1");
Socket b = ss.accept();
System.err.println("2");
Socket c = ss.accept();
System.err.println("3");
}
}