java tcp client and server - java

I have the following host
package clserver;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Main {
//instance vars
static ServerSocket sSocket = null;
static int serverPort = 0;
static Socket cSocket = null;
static PrintWriter out = null;
static BufferedReader in = null;
public static void main(String[] args) throws IOException {
System.out.println("\n\n\nTCP Server Client\n\nEnter port number:");
Scanner scan = new Scanner(System.in);
serverPort = scan.nextInt();
try {
//connect server to port
sSocket = new ServerSocket(serverPort);
} catch (IOException ex) {
System.err.println("That port is busy");
}
try {
//accept client connection
cSocket = sSocket.accept();
} catch (IOException ex) {
System.err.println("Connection failed");
}
out = new PrintWriter(cSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(cSocket.getInputStream()));
System.out.println(in.readLine());
}
}
and this client code
package clclient;
import java.io.*;
import java.net.*;
import java.net.UnknownHostException;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Main {
//instance vars
static Socket cSocket =null;
static PrintWriter out = null;
static BufferedReader in = null;
//server info
static String serverName = null;
static int serverPort = 0;
public static void main(String[] args) {
try {
System.out.println("\n\n\nTCP Chat Client\nEnter server name:");
Scanner scan = new Scanner(System.in);
//get server info from user
serverName = scan.nextLine();
System.out.println("\nEnter port number:");
serverPort = scan.nextInt();
//make connection to server
cSocket = new Socket(serverName, serverPort);
out = new PrintWriter(cSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(cSocket.getInputStream()));
} catch (UnknownHostException ex) {
System.err.println("\ncan't find that host\n");
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
String nm = "testing";
out.print(nm);
}
}
I am trying to send messages back and forth between them but when I send a message the host crashes. It throws the exception Java.net.SocketException:connection reset

Nope. print() just sends the data. println() sends the data and a line terminator. readLine() blocks until a line terminator is received. So somewhere along the line you have to call println(), or send a line terminator some other way.

I haven't used Java sockets for a while, but the following fixes it on my machine:
In the client, call out.println(nm) instead of out.print(nm).
I think it may have something to do with automatic flushing, where println autoflushes but print does not. Still, not sure off the top of my head why print would cause a Socket exception.
Edit: you really should be doing everything with the Sockets within a try, and have a finally that calls close() on the Sockets.

Related

Trouble with simple java socket and thread program

I'm trying to learn how to use threads alongside sockets in java. I have a very simple program. Its function is to have the user input a string and to have that message received and printed out by the server whose socket is running inside of a thread. I get it to print out "Connection established!" and to accept inputs from the user, but they never seem to print out. Is there some reason why received messages aren't being printed to the console?
Here is the Client class:
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws IOException {
InetAddress host = InetAddress.getLocalHost();
TCPServer newServer = new TCPServer(5001);
Thread thread = new Thread(newServer);
thread.start();
Socket socket = new Socket(host,5001);
String outgoing_message = "";
Scanner scan = new Scanner(System.in);
PrintWriter printer = new PrintWriter(socket.getOutputStream());
while(!outgoing_message.equals("close")) {
System.out.print("Enter message: ");
outgoing_message = scan.nextLine();
printer.println(outgoing_message);
}
socket.close();
}
}
And here is the TCPServer class:
package Package_Two;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class TCPServer implements Runnable{
private Socket socket;
private ServerSocket serverSocket;
public TCPServer(int port) throws IOException{
this.serverSocket = new ServerSocket(port);
}
#Override
public void run(){
try {
this.socket = serverSocket.accept();
System.out.println("Connection established!");
Scanner scan = new Scanner(socket.getInputStream());
String incoming_message = "";
while(!incoming_message.equals("close")){
incoming_message = scan.nextLine();
System.out.println("Received message: " + incoming_message);
}
socket.close();
}
catch(IOException iex){
iex.printStackTrace();
}
}
}
If you will take a look at source code of PrintWriter constructor you used, you will spot that it invoke another constructor with autoFlush = false.
I suppose, you should change it to:
PrintWriter printer = new PrintWriter(socket.getOutputStream(), true);

Handle java.net.SocketException: Socket closed when multithreading?

I'm doing a school project where we are supposed to create a simplefied Hotel booking system and then use it with a server/client communication.
Since I wanted to push the project a bit and do a multithreaded program, I've got a Socket Exception that I'm not sure how to handle. I've searched everywhere for an answer and I know that the exception occours because I'm trying to use a socket that has been closed. But from what I've read on Oracle-docs, their example is doing that as well.
So, is this actually Ok, just that I need to handle the exception? Cause my code runs fine, I just see the exceptions since I've put e.printStackTrace(); in my catch.
My Client class:
package client;
import java.io.*;
import java.net.Socket;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
try {
Socket client = new Socket("localhost", 6066);
//System.out.println("Just connected to " + client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
LocalDate localDate = LocalDate.now();
String date = DateTimeFormatter.ofPattern("yyy/MM/dd").format(localDate);
System.out.println(in.readUTF());
System.out.print("Namn: ");
String name = sc.nextLine();
System.out.print("Ålder: ");
String age = sc.nextLine();
out.writeUTF(name);
out.writeUTF(age);
out.writeUTF(date);
System.out.println(in.readUTF());
client.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
And my Server class:
package server;
import java.io.IOException;
import java.net.*;
public class Server {
public static void main(String [] args) throws IOException {
int port = 6066;
ServerSocket server = new ServerSocket(port);
while(true) {
System.out.println("Listening for client..");
try {
Socket connectedClient = server.accept();
ClientHandle ch = new ClientHandle(connectedClient);
Thread t = new Thread((Runnable) ch);
t.start();
}catch (IOException e) {
}
}
}
}
And then my ClientHandle class which has the run() for the server-side:
package server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.net.*;
import resources.*;
public class ClientHandle implements Runnable{
Socket connectedClient;
DataInputStream in;
DataOutputStream out;
public ClientHandle(Socket connectedClient) {
this.connectedClient = connectedClient;
try{
this.in = new DataInputStream(this.connectedClient.getInputStream());
this.out = new DataOutputStream(this.connectedClient.getOutputStream());
}catch(IOException ex) {
}
}
Hotel hotel = new Hotel();
Ticket yourTicket = new Ticket();
Server server = new Server();
#Override
public void run() {
while (true) {
try {
InetAddress host = InetAddress.getLocalHost();
System.out.println("Client " + host + " has connected.");
out.writeUTF("Välkommen till Hotel Gisslevik!\nVänligen fyll i nedan information för att slutföra din bokning.\n");
String yourName = in.readUTF();
String age = in.readUTF();
int yourAge = Integer.parseInt(age);
String date = in.readUTF();
yourTicket.setDate(date);
Person guest = new Person(yourName, yourAge);
hotel.setRooms();
Integer room = hotel.getRoom();
String rent = "J";
if (rent.indexOf("J") >= 0) {
yourTicket.setId(yourName);
if (hotel.checkIn(guest, room, yourTicket.getId(), yourTicket.getDate())) {
String yourId = yourTicket.getId();
out.writeUTF("\nDitt rum är nu bokat den " + date + ". \nBokningsnummer: " + yourId);
}
}
out.flush();
connectedClient.close();
}catch (EOFException e) {
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
}
If I just comment e.printStackTrace(); the exceptions doesn't show, but I would like to know how to handle them (if they should be handled). I've been searching the internet for days and checked out tutorials, but I don't find a proper answer to this.
I really appreciate any help you can provide.
Handle java.net.SocketException: Socket closed
Don't close the socket and then continue to use it.
when multithreading?
Irrelevant.
You have connectedClient.close() inside your while (true) loop. Solution: move it outside.

How do I reconnect a client when server is down in Java?

I have a server that accepts sockets from whenever a client connects. I want to be able to shutdown my local server and let my client try to reconnect for about 5 times, and if I start my server the client should indicate that you have reconnected again.
I understand somewhat that this is done in the try{} catch(IOException){Here goes the code for handleing reconnect} I want to use the same socket that I first used to connect. I don't want to create a new Client cause then I have to enter username and stuff like that all over again
I tried to creating a new socket like clientSocket = new Socket("localhost", portnr) but I don't know if this is the correct way to go. If you have examples that answers this please link them. I dont mind reading as long as it is good documented. Thanks in advance!
EDIT.
Here is my Client Class
public class Client {
public static void main(String[] args) {
Client client = new Client();
client.connect();
}
//------------------------------------------------------------
//METHOD CONNECT
//------------------------------------------------------------
private void connect(){
int reConnectTries = 0;
Socket clientsocket;
try {
//------------------------------------------------
//Sets up variables needded for execution
clientsocket = new Socket("localhost", 8900);
DataOutputStream OUT = new DataOutputStream(clientsocket.getOutputStream());
ListenforMessages listen = new ListenforMessages(clientsocket);
//We don't want to enter username all the time
//So this goes not in the while-loop
//------------------------------------------------
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter username");
String username = keyboard.nextLine();
//Sends username to sever so it can be added to a list
OUT.writeUTF(username);
//------------------------------------------------
//------------------------------
//Creates a thread to listen on messages from server(Other clients in this case)
Thread trd = new Thread(listen);
trd.start();
//------------------------------
while (true) {
try {
String sendMessage = keyboard.nextLine();
OUT.writeUTF(sendMessage);
OUT.flush();
} catch (Exception e) {
System.err.println("Could not send message to server. " + e);
}
}
} catch (IOException e) {
System.err.println("Couldnt establish a connection: " + e);
}
}
//------------------------------------------------------------
//CLASS FOR HANDLEING INPUT. We create a class for input on a new thread
//This is cause we don't want it to block other processes.
//----------------------------------------------------------------
class ListenforMessages implements Runnable{
Socket mySocket;
DataInputStream IN;
public ListenforMessages(Socket X) throws IOException {
this.mySocket = X;
}
#Override
public void run() {
try {
IN = new DataInputStream(mySocket.getInputStream());
while (true) {
System.out.println(IN.readUTF());
}
} catch (Exception e) {
System.err.println("Couldn't fetch message from server.Error: " + e);
}
}
}
}
There's a couple of solutions to this problem, but a simple one would to be have the client try to reconnect (open a new connection to the server) at set intervals. For example, you could try something like this to have your client try to reconnect once every 3 minutes:
while(true) {
try {
clientSocket = new Socket("localhost", portnr);
break; // We connected! Exit the loop.
} catch(IOException e) {
// Reconnect failed, wait.
try {
TimeUnit.MINUTES.sleep(3);
} catch(InterruptedException ie) {
// Interrupted.
}
}
}
This way, the client will try to connect, and if it fails, wait for 3 minutes before trying again.
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.NoRouteToHostException;
import java.net.SocketAddress;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.net.ConnectException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.DataOutputStream;
import java.io.DataInputStream;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
final class TCPClient{
private static Scanner in ;
private static DataOutputStream douts;
private static OutputStream outs;
private static InputStream ins;
private static DataInputStream dins;
private static String ip;
private static Integer port;
private int count = 0;
private static int times;
public TCPClient(){
serverConTest(port);
}
private boolean portIsOpenOrNot(String ip, int port){
try{
Socket socket = new Socket();
socket.connect(new InetSocketAddress(ip,port),500);
socket.close();
return true;
}catch(Exception e){
}
return false;
}
private void serverConTest(int port){
while(true){
try{
InetAddress addr = InetAddress.getByName(ip);
SocketAddress sockaddr = new InetSocketAddress(addr,port);
Socket socket = new Socket();
System.out.println("Connecting To server...");
socket.connect(sockaddr);
Thread.sleep(1000);
boolean isactive = true;
if(portIsOpenOrNot(ip,port)){
outs = socket.getOutputStream();
douts = new DataOutputStream(outs);
System.out.println("Sending Request to server:");
while(isactive){
Thread.sleep(1000);
douts.writeUTF("Are you Alive..!");
ins = socket.getInputStream();
dins = new DataInputStream(ins);
System.out.println("Response from server : "+dins.readUTF());
}
}
}catch(SocketException e){
System.out.println("Connection lost");
}catch(IOException e){
break;
}catch(InterruptedException e){
System.out.print("connection timeout in 50 second.");
break;
}
}
}
public static void main(String[] args){
in = new Scanner(System.in);
System.out.print("Enter ip : ");
ip = in.nextLine();
System.out.print("Enter Port : ");
port = Integer.parseInt(in.next());
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future future = executorService.submit(new Runnable() {
public void run() {
new TCPClient();
}
});
try{
future.get(50, TimeUnit.SECONDS);
}catch(InterruptedException e){
}catch(ExecutionException e){
}catch(TimeoutException e){
executorService.shutdownNow();
}
}
}
This sample will give you the complete understanding that when the server restarts then client will reconnects.
I didnt read all your code but this one is working for me
And dont forget to add the Server class and the method send that sends messages...
Client :
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class Client {
static Socket sock=null;
static DataInputStream in=null;
static DataOutputStream out=null;
static boolean connected=false;
static String currentip="";
static int currentport=0;
static void refreching(){
try {
in=new DataInputStream(sock.getInputStream());
out=new DataOutputStream(sock.getOutputStream());
Thread gg=new Thread() {
String msg="";
public void run() {
while(connected) {
try {
msg=in.readUTF();
System.out.println(msg);
} catch (IOException e) {
connected=false;
System.out.println("Reconnecing...");
while(!connected)
connect(currentip,currentport);
}
}
}
};
gg.start();
}
catch(Exception e) {
System.out.println("Problem while reading incoming and outgoing"+
"messages!");
connected=false;
}
}
static void connect(String iphost, int port){
try{
sock=new Socket(iphost,port);
currentip=iphost;
currentport=port;
connected=true;
refreching();
System.out.println("Connected!");
}
catch(Exception e){
System.out.println("Cant connect !");
connected=false;
}
}
public static void main(String[] args) {
connect("127.0.0.1",1234); //Example you can enter another's computer ip
//adress if connected to the same network !!!
//Send(Message_To_Server); Dont forget to add the sending code!!!
//Maybe i'll upload a video one day==>how to create a chat application
}

Java TCP Client Server Hangs Up?

I am currently having difficulty understanding why my code is not working. I've included my client and server code below. I've figured out that my problem happens somewhere in the while loops but I'm not sure how to fix it so that it doesn't get stuck. I've searched around the forum for a while and some said adding a newline character would fix it, but I'm still having trouble.
My main question is how can I avoid the process from getting stuck and not communicating properly. Can anybody out there point me in the right direction?
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class My_Client {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket s = new Socket("localhost", 5555);
BufferedReader r = new BufferedReader(new InputStreamReader(
s.getInputStream()));
PrintStream w = new PrintStream(s.getOutputStream());
w.print("hello world");
w.print('\n');
String line;
while ((line = r.readLine()) != null) {
System.out.println("Received: " + line);
//System.out.println("Error");
}
w.close();
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
-----------------------------------------------------------------
public class My_Server {
private static final int PORT = 5555;
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(PORT);
System.out.println("Server Socket Created");
while (true) {
System.out.println("Waiting on connection");
Socket cs = ss.accept();
System.out.println("Client connected");
BufferedReader r = new BufferedReader(new InputStreamReader(
cs.getInputStream()));
PrintStream w = new PrintStream(cs.getOutputStream());
String line;
while ((line = r.readLine()) != null) {
w.print(line + "!!!!");
w.print('\n');
}
System.out.println("Client disconnected");
r.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Both ends are reading until EOS and neither is closing until after that. So you have a classic deadlock. You need to rethink your application protocol.
You also need to tell your PrintStream or PrintWriter to autoflush, or else call flush() yourself, but this is a relatively minor matter compared to the mistake above.
You should use autoflush on your PrintWriters like this:
PrintStream w = new PrintStream(cs.getOutputStream(),true);
You can setup a PROTOCOL to end the communication something like this:
In your client:
w.println("[END]");
In your server:
while (!(line = r.readLine()).equals("[END]")) {
Hope this helps:
Check the comments
And be sure that you get Client Connected on console of server side
CLIENT SIDE
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class My_Client {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket s = new Socket("localhost", 5555);
BufferedReader r = new BufferedReader(new InputStreamReader(
s.getInputStream()));
PrintStream w = new PrintStream(s.getOutputStream());
w.print("hello world");
w.print("\n"); // enter new line
w.flush();// flush the outputstream
String line;
while ((line = r.readLine()) != null) {
System.out.println("Received: " + line);
//System.out.println("Error");
}
w.close();
}
}
SERVER SIDE
----------------------------------------------------------
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
public class My_Server {
private static final int PORT = 5555;
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(PORT);
System.out.println("Server Socket Created");
while (true) {
System.out.println("Waiting on connection");
Socket cs = ss.accept();
System.out.println("Client connected");
BufferedReader r = new BufferedReader(new InputStreamReader(
cs.getInputStream()));
PrintStream w = new PrintStream(cs.getOutputStream());
String line;
while ((line = r.readLine()) != null) {
w.print(line + "!!!!");
w.print("\n");// entering new line
}
System.out.println("Client disconnected");
r.close();
w.close();// close w
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

java tcp socket can't send file to server side

I'm new to java socket programming, this program allows TCP server to have a multi-thread that can run concurrently. I try to send the txt file from one client(has another client that will sent file at the same time) to the server side and ask server to send "ok" status message back to client side. But it seems that the server can't receive any file from the client and the strange thing is if i delete the receiveFile() method in my client class, the server is able to recieve the file from client. Can somebody help me?
Server.class
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
public class ConcurrentServer {
public static void main(String args[]) throws IOException
{
int portNumber = 20020;
ServerSocket serverSocket = new ServerSocket(portNumber);
while ( true ) {
new ServerConnection(serverSocket.accept()).start();
}
}
}
class ServerConnection extends Thread
{
Socket clientSocket;
ServerConnection (Socket clientSocket) throws SocketException
{
this.clientSocket = clientSocket;
setPriority(NORM_PRIORITY - 1);
}
public void run()
{
try{
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
OutputStream outToClient = clientSocket.getOutputStream();
PrintWriter printOutPut = new PrintWriter(outToClient,true);
while(inFromClient.ready())
{
String request = inFromClient.readLine();
System.out.println(request);
System.out.println("test");
}
printOutPut.write("HTTP/1.1 200 OK\nConnection: close\n\n");
printOutPut.write("<b> Hello sends from Server");
printOutPut.flush();
printOutPut.close();
clientSocket.close();
}
catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
Client.class
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class SmallFileClient {
static String file="test.txt";
static PrintWriter outToServer;
static Socket socket;
public static void main(String[] args) throws IOException
{
final int PORT=20020;
String serverHostname = new String("127.0.0.1");
socket = new Socket(serverHostname, PORT);
outToServer = new PrintWriter(socket.getOutputStream(),true);
sendFile();
receiveFile();
outToServer.flush();
outToServer.close();
socket.close();
}
//read file and send file to server
public static void sendFile() throws IOException
{
BufferedReader br=new BufferedReader(new FileReader(file));
try
{
String line = br.readLine();
while(line!=null)
{
//send line to server
outToServer.write(line);
line=br.readLine();
}
}catch (Exception e){System.out.println("!!!!");}
br.close();
}
//get reply from server and print it out
public static void receiveFile() throws IOException
{
BufferedReader brComingFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
try
{
String inline = brComingFromServer.readLine();
while(inline!=null)
{
System.out.println(inline);
inline = brComingFromServer.readLine();
}
}catch (Exception e){}
}
}
Get rid of the ready() test. Change it to:
while ((line = in.readLine()) != null)
{
// ...
}
readLine() will block until data is available. At present you are stopping the read loop as soon as there isn't data available to be read without blocking. In other words you are assuming that `!ready()! means end of stream. It doesn't: see the Javadoc.

Categories