I have a question, I'm currently working on a little project of mine and stumbled upon a dead end. I have a Java Server :
import java.io.*;
import java.net.*;
class TCPServer
{
public static void main(String argv[]) throws Exception
{
ServerSocket welcomeSocket = new ServerSocket(3443);
Socket clientSocket =null;
ClientHandler ch;
while(true)
{
try{
clientSocket = welcomeSocket.accept();
System.out.println("Client connected on port :"+clientSocket.getPort());
ch = new ClientHandler (clientSocket);
Thread t = new Thread(ch);
t.start();
}catch (Exception e){
System.out.println("SERVER CRASH");
}
}
}
}
Then the client connects through the port 3443, a new thread is created with ClientHandler. Now is the problem, in the client side the socket used to connect is still on port 3443, but on the server side the thread is on an arbitrary port, let's say 5433, so the server can communicate with the thread but not the client, because it has no knowledge of what port the thread is using... I'm a bit confused with all this, does the client class is only needed to make the initial connection, then all the communication is done through the ClientHandler class, if so should i also instantiate an object of ClientHandler in the client class?
Here's my client class :
import java.io.*;
import java.net.*;
class TCPClient
{
static Socket clientSocket = null;
public static void main(String argv[]) throws Exception
{
BufferedReader k = new BufferedReader(new InputStreamReader(System.in));
BufferedReader ine = null;
DataOutputStream oute = null;
try{
clientSocket = new Socket("localhost", 3443);
oute = new DataOutputStream(clientSocket.getOutputStream());
ine = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (UnknownHostException e) {
System.out.println("Unknown host");
System.exit(1);
} catch (IOException e) {
System.out.println("No I/O");
System.exit(1);
}
try{
//send
oute.writeBytes(k.readLine());
//recieve
String line = ine.readLine();
System.out.println("Text received: " + line);
} catch (IOException e){
System.out.println("Read failed");
System.exit(1);
}
}
}
The problem is the socket created in client is still connected to Port 3443, and the server is listening to this port, so I won't recieve anything from the server (infinite loop). The clientHandler is on another port. Am i doing it wrong?
You’re calling accept() twice. Call it only once and store the resulting Socket in a variable that you can then hand in to new ClientHandler().
Oh, also, the Socket knows both sides of the communication so it won’t be confused by whatever port the client uses.
Related
I have written a simple Java TCP Server and a Client (See below).
The idea is quite simple: the Client sends a message to the Server the Server reads it, modify it and sends it back to the client.
import java.io.*;
import java.net.*;
public class ServerTest2 {
public static void main(String[] argv) {
try {
ServerSocket serverSocket = new ServerSocket(2000); // Create Socket and bind to port 2000
System.out.println("Created");
Socket clientSocket = serverSocket.accept(); //Wait for client and if possible accept
System.out.println("Connection accepted");
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())); // for outputs
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); // for inputs
String request; // requst/input of client
String answer; // the answer for the client
System.out.println("Start Waiting");
request = br.readLine(); //Wait for input from client
answer = "answer to "+request;
bw.write(answer); // Send answer to client
System.out.println("send");
bw.newLine();
bw.flush();
//Shut everything down
bw.close();
br.close();
clientSocket.close();
serverSocket.close();
}
catch (Exception e) {
System.out.println(e);
}
}
}
The Client Implementation
import java.io.*;
import java.net.*;
public class ClientTest2 {
public static void main(String[] argv) {
try {
String host = "185.75.149.8"; //public ip of router
Socket clientSocket = new Socket(host,2000); //Create and connect Socket to the host on port 2000
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())); // for outputs
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); // for inputs
String answer;
String request = "HelloWorld";
bw.write(request); //Write to server
bw.newLine();
bw.flush();
System.out.println("Waiting");
answer = br.readLine(); //Wait for answer
System.out.println("Host = "+host);
System.out.println("Echo = "+answer);
//Shut eveything down
bw.close();
br.close();
clientSocket.close();
}
catch (Exception e) {
System.out.println(e);
}
}
}
It works perfectly on my local network.
Now I want to use it via the Internet so I installed Port Forwarding on Port 2000 in my Router which sends it to Port 2000 of my PC.
My PC is directly connected to my Router without any Subnets in between.
The Problem is that the Server does not accept the connection(Stops at serverSocket.accept()).
It does not throw an Exception it just waits forever.
The Client does also not throw an Exception (If the Port isn't open it would throw a Connection refused Exception)
This means that the Port Forwarding should work (I have also tested whether the port is open with a Webtool (its open)).
But strangely the Client stops waiting after about 10 seconds and continues with the program.
Since the Port Forwarding should work and my Code works fine in my local Network I absolutely don't know how or where I could find the problem.
I appreciate any help.
Thank you very much!
Hello programmers on the internet. I am currently stepping through an operating systems book and there are some exercises that involve the following pieces of code.
This is the server code
import java.net.*;
import java.io.*;
public class DateServer{
public static void main(String[] args) {
try {
ServerSocket sock = new ServerSocket(6013);
// now listen for connections
while (true) {
Socket client = sock.accept();
PrintWriter pout = new
PrintWriter(client.getOutputStream(), true);
// write the Date to the socket
pout.println(new java.util.Date().toString());
// close the socket and resume
// listening for connections
client.close();
}
}
catch (IOException ioe) {
System.err.println(ioe);
}
}
}
This is the client code
import java.net.*;
import java.io.*;
public class DateClient{
public static void main(String[] args) {
try {
//make connection to server socket
Socket sock = new Socket("127.0.0.1",6013);
InputStream in = sock.getInputStream();
BufferedReader bin = new
BufferedReader(new InputStreamReader(in));
// read the date from the socket
String line;
while ( (line = bin.readLine()) != null)
System.out.println(line);
// close the socket connection
sock.close();
}
catch (IOException ioe) {
System.err.println(ioe);
}
}
}
So to my understanding the server is creating a socket and writing a date value to it. The client is then coming a long and connecting to the server and writing out the value in that socket. Am I interpreting this code correctly? This is my first experience with sockets.
Now for my actual question. I want to have the client connect to the server (and print out a message saying you are connected) and then be able to send a value over to the server so that the server can process it. How would I go about doing this? I have tried tinkering with DataOutputStream and DataInputStream but I have never used either before. Any help would be GREATLY appreciated.
You are correct. You have the server writing to the socket and the client reading from the socket. You want to reverse that.
Server Should look like:
ServerSocket sock = new ServerSocket(6013);
// now listen for connections
while (true)
{
Socket client = sock.accept();
InputStream in = client.getInputStream();
BufferedReader bin = new BufferedReader(new InputStreamReader(in));
// read the date from the client socket
String line;
while ((line = bin.readLine()) != null)
System.out.println(line);
// close the socket connection
client.close();
}
The client should look like:
try
{
// make connection to server socket
Socket sock = new Socket("127.0.0.1", 6013);
PrintWriter out = new PrintWriter(sock.getOutputStream(), true);
// send a date to the server
out.println("1985");
sock.close();
}
catch (IOException ioe)
{
System.err.println(ioe);
}
I'm trying to program a Server Client program where the CLIENT will be prompt if the SERVER closes or loses connection. What happens is once I connect the server and the client then disconnects the server it doesn't go to the ConnectException part
example: I opened the Server and Client connects, in the Client it will show that "You are connected to the Server", then if the Server disconnects there should be a "Server is disconnected". and when the Server reopens it will prompt the Client that he's connected to the Server
How can I continuously check if the Server is open or disconnected
here's my code:
SERVER
public class Server
{
private static Socket socket;
public static void main(String[] args)
{
try
{
int port = 25000;
ServerSocket serverSocket = new ServerSocket(port);
//Server is running always. This is done using this while(true) loop
while(true)
{
//Reading the message from the client
socket = serverSocket.accept();
System.out.println("Client has connected!");
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String number = br.readLine();
System.out.println("Message received from client is "+number);
//Multiplying the number by 2 and forming the return message
String returnMessage;
try
{
int numberInIntFormat = Integer.parseInt(number);
int returnValue = numberInIntFormat*2;
returnMessage = String.valueOf(returnValue) + "\n";
}
catch(NumberFormatException e)
{
//Input was not a number. Sending proper message back to client.
returnMessage = "Please send a proper number\n";
}
//Sending the response back to the client.
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returnMessage);
System.out.println("Message sent to the client is "+returnMessage);
bw.flush();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
CLIENT
public class Client
{
private static Socket socket;
public static void main(String args[])
{
Scanner input=new Scanner(System.in);
try
{
String host = "localhost";
int port = 25000;
InetAddress address = InetAddress.getByName(host);
socket = new Socket(address, port);
System.out.println("Connected to the Server");
}
catch (ConnectException exception)
{
System.out.println("Server is still offline");
}
catch(IOException ex)
{
System.out.println("Server got disconnected");
}
}
}
Well, the best way to tell if your connection is interrupted is to try to read/write from the socket. If the operation fails, then you have lost your connection sometime.
So, all you need to do is to try reading at some interval, and if the read fails try reconnecting.
The important events for you will be when a read fails - you lost connection, and when a new socket is connected - you regained connection.
That way you can keep track of up time and down time.
you can do like this
try
{
Socket s = new Socket("address",port);
DataOutputStream os = new DataOutputStream(s.getOutputStream());
DataInputStream is = new DataInputStream(s.getInputStream());
while (true)
{
os.writeBytes("GET /index.html HTTP/1.0\n\n");
is.available();
Thread.sleep(1000);
}
}
catch (IOException e)
{
System.out.println("connection probably lost");
e.printStackTrace();
}
or you can simply et connection time out like this socket.setSoTimeout(timeout); to check connectivity
or you can use
socket.getInputStream().read()
makes the thread wait for input as long as the server is connected and therefore makes your program not do anything - except if you get some input and
returns -1 if the client disconnected
or what you can do is structure your code in this way
while(isConnected())
{
// do stuffs here
}
I need to make a TCP Server which accepts sockets from clients and receives data from them and send received data to all clients. to do that my Server class saves accepted connections to an ArrayList<Socket> and while wants to send data to clients:
Arraylist<Socket> sockets=Server.getSockets();
for(Socket current: sockets)
{
ObjectOutputStream out=new ObjectOutputStream (current.getOutputStream());
out.flush();
out.writeObject(object);
out.flush();
out.close();
}
but it doesn't work. what's wrong?
There is nothing wrong with your code snippet, the only problem which I can feel is that how your client code is implemented. Let us say your client code is something like this.
Socket clientSocket = new Socket(ip, port);
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
while ( true ){
String sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');
outToServer.flush();
DataInputStream is = new DataInputStream(clientSocket.getInputStream());
System.out.println(is.readLine());
}
Now this client is reading input from console and sending it to server, post that it blocks to wait for response. Lets assume server will send data to all[Which is what you want] if he receive a message 'fire'.
Now there are two clients connected to server, ClientA and ClientB.
1. ClientA blocked at user-input (console)
2. User enter 'abc'
3. ClientA moves on sends 'abc' to server
4. ClientA blocks to read data from server
5. Server sends back 'abc' to ClientA [Assuming its an echo server]
6. ClientA reads the data, print it
7. ClientA moves back(while loop), blocked again for user input.
Same thing happen for ClientB, so now both are blocked for user input from console.
Lets say now ClientA user send our magic word ['fire' in this case], server identifies that its a magic word and start sending data to ClientA and ClientB,
Now here the important thing to notice, which is the state of ClientA and ClientB, at this point ClientA has just send the data and is at point 4, hence is blocked to read data from server, so when server sends the message it can read and display, whereas clientB is at point 1, blocked for getting data from console.. so even though server has send data ClientB has data to read, but it can't since its stuck at point 1, also you are closing the connection from server after write, so if ClientB somehow after sometime moves from point 1 to point 4, socket is already closed, hence again it will not be able to read. Though server has send data to both ClientA and ClientB, only ClientA is able to get it.
Phew!! Quite a long explanation, I guess it gives you some direction to solve your problem
Server code for reference
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class BroadCastTCPServer {
private static ArrayList<Socket> sockets = new ArrayList<Socket>();
//Usage: java TCPServer port
public static void main(String args[]){
BroadCastTCPServer server = new BroadCastTCPServer();
try {
server.startServer("9999");
} catch (Exception e) {
e.printStackTrace();
}
}
private void startServer(String portStr) throws IOException {
int port = Integer.parseInt(portStr);
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("Listening on IP:" + serverSocket.getInetAddress().getHostAddress() + " Port:"+port);
while(true){
Socket connectionSocket = serverSocket.accept();
sockets.add(connectionSocket);
System.out.println("New client connection:" + connectionSocket.getRemoteSocketAddress());
ClientHandler cl = new ClientHandler(connectionSocket);
Thread clientThread = new Thread(cl);
clientThread.start();
}
}
public void sendAll() throws Exception{
System.out.println("No of connections:" + sockets.size());
for(Socket current: sockets){
System.out.println(current.getRemoteSocketAddress());
ObjectOutputStream out=new ObjectOutputStream (current.getOutputStream());
out.flush();
out.writeObject("Tata\n");
out.flush();
//out.close();
}
}
class ClientHandler implements Runnable{
Socket socket;
public ClientHandler(Socket socket){
this.socket = socket;
}
#Override
public void run() {
BufferedReader inFromClient = null;
ObjectOutputStream out = null;
BufferedWriter br = null;
try {
inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out=new ObjectOutputStream (socket.getOutputStream());
OutputStreamWriter or= new OutputStreamWriter(out);
br = new BufferedWriter(or);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while(true){
String clientSentence= null;
try {
clientSentence = inFromClient.readLine() ;
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("Received: " + clientSentence);
if (clientSentence.equalsIgnoreCase("fire")) {
try {
sendAll();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
try {
br.write(clientSentence + "\n" );
br.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
I am trying to write server to client program but I cannot communicate with the server in Java.
Here is the code block in my main.
InetAddress addr = InetAddress.getLocalHost();
ipAddress = "78.162.206.164";
ServerSocket serverSocket = new ServerSocket(0);
String randomStringForPlayerName = RandomStringGenerator.generateRandomString();
baseForReqOpp += ipAddress + " " + serverSocket + " " + randomStringForPlayerName;
Socket socket = new Socket(host,2050);
socket.setSoTimeout(100);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream());
out.write(baseForReqOpp);
out.flush();
System.out.println(in.read());
I know that there is no problem in the server code and all the communication ports are ok.
But I cannot read anything from the server.
What can be the problem?
you have to create an output stream before the input stream
Here is some working code with communicating client and server sockets. Hopefully you can adapt it for your specific problem.
public class SocketTest {
public void runTest() {
try {
// create the server
new SimpleServer().start();
// connect and send a message
InetAddress addr = InetAddress.getLocalHost();
Socket sock = new Socket(addr, 9090);
ObjectOutputStream out = new ObjectOutputStream(sock.getOutputStream());
out.writeObject("Hello server");
out.flush();
ObjectInputStream in = new ObjectInputStream(sock.getInputStream());
System.out.println("from server: " + in.readObject());
sock.close();
} catch (Exception e) {
e.printStackTrace();
}
}
// server has to run in a separate thread so the code doesn't block
private class SimpleServer extends Thread {
#Override
public void run() {
try {
ServerSocket sock = new ServerSocket(9090);
Socket conn = sock.accept();
// the code blocks here until a client connects to the server
ObjectInputStream in = new ObjectInputStream(conn.getInputStream());
System.out.println("from client: " + in.readObject());
ObjectOutputStream out = new ObjectOutputStream(conn.getOutputStream());
out.writeObject("Hello client");
out.flush();
sock.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
To run it:
new SocketTest().runTest();
Your code will never work because you don't use threads. In order to start the server, you need to call accept at some point in your code
myServerSocket.accept();
this is a blocking call, ie the code flow stops until a client connects. But since you can't execute any statement (remember accept is blocking?) how can a client connect? This chicken and egg problem is resolved through threads. See Howard's answer for a code sample.
I don't see any call to accept(), so I wonder what your client connects to...