I tried to create a simple chat via sockets and it works for LAN right now and for "localhost" too, of course, but not among different computers through the internet and thats the real point of a chat, isn't it!
socket = new Socket("--ip address--", 7345);
This line works for --ip address-- = localhost and --ip address-- = ""my local ip-address"", but with the ip address of my router, it throws a java.net.ConnectException
" java.net.ConnectException: Connection refused: connect "
I want to use my pc as server and not a real server, maybe there is the problem, but I think that there must be a solution. If that is an absurd simple question, don't doom me, because I'm a real newbie in network programming.
When you are creating a server, you have to use server socket with the ip address of where it's running...
The server socket needs to be running on your machine of your machine's ip address.
With your router, you need to forward the connections to the port you are running on your that is hosting the server.
Then you should be able to connect from outside your local network.
Without the code for what your are doing it's hard to tell if that's the only problem here is a simple chat server that might give you guidance.
import java.net.*;
import java.io.*;
public class ChatServer
{ private Socket socket = null;
private ServerSocket server = null;
private DataInputStream streamIn = null;
public ChatServer(int port)
{ try
{
System.out.println("Binding to port " + port + ", please wait ...");
server = new ServerSocket(port);
System.out.println("Server started: " + server);
System.out.println("Waiting for a client ...");
socket = server.accept();
System.out.println("Client accepted: " + socket);
open();
boolean done = false;
while (!done)
{ try
{ String line = streamIn.readUTF();
System.out.println(line);
done = line.equals(".bye");
}
catch(IOException ioe)
{
done = true;
}
}
close();
}
catch(IOException ioe)
{ System.out.println(ioe);
}
}
public void open() throws IOException
{ streamIn = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
}
public void close() throws IOException
{ if (socket != null) socket.close();
if (streamIn != null) streamIn.close();
}
public static void main(String args[])
{ ChatServer server = null;
if (args.length != 1)
System.out.println("Usage: java ChatServer port");
else
server = new ChatServer(Integer.parseInt(args[0]));
}
}
Related
I have a server whose port 80 is for occupied by HTTP transactions. I wanted to see the traffic in that port and I tried to use a socket program to listen to that port.
public Server(int serverPort) throws IOException {
super(serverPort);
try {
while (true) {
Socket socket = accept();
new ServerThread(socket);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
close();
}
}
// inner-class ServerThread
class ServerThread extends Thread {
private Socket socket;
private BufferedReader in;
private PrintWriter out;
// Ready to conversation
public ServerThread(Socket s) throws IOException {
this.socket = s;
in = new BufferedReader(new InputStreamReader(socket
.getInputStream(), "UTF-8"));
out = new PrintWriter(socket.getOutputStream(), true);
start();
}
// Execute conversation
public void run() {
try {
// Communicate with client until "bye " received.
while (true) {
String line = in.readLine();
if (line == null || "".equals(line.trim())) {
break;
}
System.out.println("Received message: " + line);
out.println(line);
out.flush();
}
out.close();
in.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
new Server(80);
}
However, when I run that java application, it showed a BindException: Address already in use.
So what should I do to my code and make it listen to port 80, or are there any other ways to listen to that port in Java?
If I understand you correctly you are trying to sniff the packets that are being passed to your server. If that is the case there are some answers in this post.
What Server are you running it on?
it all depends on the type of server you're working on. Tomcat for example has the type of port it's running off of in the Server.xml file.
In Windows you can run your program by administrator. In Linux using root user.
I have a simple pair of client and server programs. Client connects to server and when it does connect, the server replies with a "Hello there" message. How should I modify the program if I want the client and server programs to run on different systems?
Here is the code for the client side..
package practice;
import java.io.*;
import java.net.*;
public class DailyAdviceClient
{
public static void main(String args[])
{
DailyAdviceClient dac = new DailyAdviceClient();
dac.go();
}
public void go()
{
try
{
Socket incoming = new Socket("127.0.0.1",4242);
InputStreamReader stream = new InputStreamReader(incoming.getInputStream());
BufferedReader reader = new BufferedReader(stream);
String advice = reader.readLine();
reader.close();
System.out.println("Today's advice is "+advice);
}
catch(Exception e)
{
System.out.println("Client Side Error");
}
}
}
and here is the code for the server
package practice;
import java.io.*;
import java.net.*;
public class DailyAdviceServer
{
public static void main(String args[])
{
DailyAdviceServer das = new DailyAdviceServer();
das.go();
}
public void go()
{
try
{
ServerSocket serversock = new ServerSocket(4242);
while(true)
{
Socket outgoing = serversock.accept();
PrintWriter writer = new PrintWriter(outgoing.getOutputStream());
writer.println("Hello there");
writer.close();
}
}
catch(Exception e)
{
System.out.println("Server Side Problem");
}
}
}
just change "127.0.0.1" on the client with the server's IP and make sure the port 4242 is open.
Socket incoming = new Socket("127.0.0.1",4242);
This is creating a socket listening to the server at the address 127.0.0.1 on port 4242. If you change the server to another address, for example of a different pc, then change the ip address that your socket is listening to.
It is also worth noting that you will probably have to open up or allow access to the ports you are using.
Client requires ip address and port of server, means ip of that system which you making server and port (4242).so in client you need to change
Socket incoming = new Socket("127.0.0.1",4242); BY
Socket incoming = new Socket("IP address of server",4242);
And make sure both system is connected via wired or wireless network.
I am learning currently about client server communication using Java through sockets.
First of all I retrieve my own machine's IP Address using following code.
InetAddress ownIP=InetAddress.getLocalHost();
//the result being 192.168.56.1
Now I write the simple client server application using the above mentioned address as follow
public class SimpleClientServer {
public static void main(String[] args)
{
//sending "Hello World" to the server
Socket clientSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try
{
clientSocket = new Socket("192.168.56.1", 16000);
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
out.println("Hello World");
out.close();
in.close();
clientSocket.close();
}
catch(IOException e)
{
System.err.println("Error occured " + e);
}
}
}
The result hower reads a follow.
Error occured java.net.ConnectException: Connection refused: connect
What is the reason for this. Is it just the wrong host address?
From the code you have given you seem to suggest that there is currently nothing listening on port 16000 for the socket to connect to.
If this is the case you need to implement something like
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(16000);
}
catch (IOException e) {
System.err.println("Could not listen on port: 16000.");
System.exit(1);
}
More information can be found in the Java online documentation and a full example is included.
With sockets, no matter what language you're using, you either initiate a connection with socket_connect or you listen and accept with socket_listen and socket_accept. Your socket_connect call is trying to connect to an ip address that doesn't seem to be listening to anything.
I'm trying to test a scenario where one server accepts connections(one each time) from one client, using always the same ports (on the server and on the client side).
The purpose is to have 1 client application sending little pieces of data at a rate bigger than 100/min. The well obvious solution would be to have an always connected link between the client and the server, but this is production stuff, and that would require bigger changes in the code that is already implemented. With the solution we have implemented today, we always have +-1K of connections in TIME_WAIT, and I want to get rid of them.
I have implemented a simple tester, and the code is:
public class Server {
public static void main(String[] args) {
ServerSocket ssock = null;
try {
ssock = new ServerSocket();
ssock.bind(new InetSocketAddress(Common.SERVER_PORT));
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
while(true){
try{
Socket cSock = ssock.accept();
BufferedReader reader = new BufferedReader(new InputStreamReader(cSock.getInputStream()));
reader.readLine();
PrintWriter writer = new PrintWriter(cSock.getOutputStream());
writer.println(Common.SERVER_SEND);
writer.flush();
reader.close();
writer.close();
cSock.close();
}catch (Exception e) {
System.out.println(e.getClass().getName() + ": " + e.getMessage());
}
}
}
}
public class Client {
public static void main(String[] args) throws Exception {
InetSocketAddress cliAddr = new InetSocketAddress(
InetAddress.getByName(args[0]),
Common.CLIENT_PORT);
InetSocketAddress srvAddr = new InetSocketAddress(
InetAddress.getByName(args[1]),
Common.SERVER_PORT);
for(int j=1;j<=50;j++){
Socket sock = null;
try{
sock = new Socket();
sock.setReuseAddress(true);
sock.bind(cliAddr);
sock.connect(srvAddr);
PrintWriter writer =
new PrintWriter(
sock.getOutputStream());
writer.println(Common.CLIENT_SEND);
writer.flush();
BufferedReader reader =
new BufferedReader(
new InputStreamReader(
sock.getInputStream()));
reader.readLine();
}catch (Exception e) {
System.out.println(e.getClass().getName() + ": " + e.getMessage());
System.exit(-1);
}finally{
if(sock!=null) sock.close();
System.out.println("Done " + j);
}
}
}
}
public class Common {
public static final int SERVER_PORT = 9009;
public static final int CLIENT_PORT = 9010;
public static final String CLIENT_SEND = "Message";
public static final String SERVER_SEND = "OK";
}
When executing the client and server, on windows hosts, in one client execution I always get
java.net.ConnectException: Connection timed out
When executing the client and the server in linux hosts, on some client executions I get a
java.net.NoRouteToHostException: Cannot assign requested address
I've been killing my head over this behavior. Can someone please tell me if it is possible to do what I want, and what I am doing wrong?
If you want to get rid of the TIME_WAIT state, don't be the peer that receives the close. Be the peer that initiates the close. In this case, close the connection immediately after reading the response, and have the server cycle around looking for another request so that it reads the EOF rather than just closing the connection immediately after sending the response. However this will only make the problem worse, as all the TIME_WAIT states will accumulate at the server rather than at the client. On the other hand, the server is now structured to accept multiple requests per connection, so then all you have to do is adapt the clients to use a connection pool and all your problems are solved.
Do I have to close all the sockets after using it? Where should I put them in this code? My program just works normally when I run it. However, when I re-run it, it said "Exception in thread "main" java.net.BindException: Address already in use: JVM_Bind". Therefore, I think I did not close all the socket after using it.
import java.io.*;
import java.net.*;
import java.util.*;
public class Server2 {
public static void main(String args[]) throws Exception {
int PORT = 5555; // Open port 5555
//open socket to listen
ServerSocket server = new ServerSocket(PORT);
Socket client = null;
while (true) {
System.out.println("Waiting for client...");
// open client socket to accept connection
client = server.accept();
System.out.println(client.getInetAddress()+" contacted ");
System.out.println("Creating thread to serve request");
ServerStudentThread student = new ServerStudentThread(client);
student.start();
}
}
}
Call server.close() in a finally block.
ServerSocket server = new ServerSocket(PORT);
try {
while (true) {
System.out.println("Waiting for client...");
// open client socket to accept connection
Socket client = server.accept();
System.out.println(client.getInetAddress()+" contacted ");
System.out.println("Creating thread to serve request");
ServerStudentThread student = new ServerStudentThread(client);
student.start();
}
} finally {
server.close();
}
Address already in use: JVM_Bind - means, that you operation system is not closed socket after previous use. It closes on timeout about 30-180 seconds.
I don't realy know how to do this in java, but in C code it may be done like this, before bind system function call:
int yes = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
That mean: set the flag (option) SO_REUSEADDR to sockfd socket.
In java must exists appropriate mechanism for do the same.
You are running an infinite while loop , have a boolean variable to say when to stop , i think you are not exiting gracefully, that is why port is not closed.
May be you can try like this
import java.io.*;
import java.net.*;
import java.util.*;
public class Server2 {
static int NUM_CONN_TO_WAIT_FOR=15;
boolean exitServer =false;
public static void main(String args[]) throws Exception {
int PORT = 5555; // Open port 5555
//open socket to listen
ServerSocket server = new ServerSocket(PORT);
Socket client = null;
static int connections =0;
try
{
while (!exitServer ) {
System.out.println("Waiting for client...");
// open client socket to accept connection
if ( connections < NUM_CONN_TO_WAIT_FOR )
{
client = server.accept();
System.out.println(client.getInetAddress()+" contacted ");
System.out.println("Creating thread to serve request");
ServerStudentThread student = new ServerStudentThread(client);
student.start();
} else
{
exitServer =true;
}
connections++;
}
} catch (Exception e)
{
System.out.println(e.printStackTrace());
}
finally
{
if ( client != null)
client.close();
if ( server!= null)
server.close();
}
}
}