So I wrote a simple Socket program that send message from Client to Server program and wanted to know what is the proper procedure to go about testing this? Both my Client and Server machines are running on Ubuntu 12.04 and I'm remote connecting to both of them.
For my Client code when I instantiate the client socket (testSocket) do I use its IP Address and Port number or Servers IP Address and Port number?
Here is the Code for Client:
public static void main(String[] args) throws UnknownHostException, IOException
{
Socket testSocket = null;
DataOutputStream os = null;
DataInputStream is = null;
try
{
testSocket = new Socket("192.168.0.104", 5932);
os = new DataOutputStream(testSocket.getOutputStream());
is = new DataInputStream(testSocket.getInputStream());
}
catch (UnknownHostException e)
{
System.err.println("Couldn't find Host");
}
catch (IOException e)
{
System.err.println("Couldn't get I/O connection");
}
if (testSocket != null && os != null && is != null)
{
try
{
os.writeBytes("Hello Server!\n");
os.close();
is.close();
testSocket.close();
}
catch (UnknownHostException e)
{
System.err.println("Host not found");
}
catch (IOException e)
{
System.err.println("I/O Error");
}
}
}
Here is the code for Server:
public static void main(String[] args)
{
String line = new String() ;
try
{
ServerSocket echoServer = new ServerSocket(5932);
Socket clientSocket = echoServer.accept();
DataInputStream is = new DataInputStream(clientSocket.getInputStream());
PrintStream os = new PrintStream(clientSocket.getOutputStream());
while (true)
{
line = is.readLine();
os.println(line);
}
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
}
I'm new to Sockets and not sure what I'm supposed be seeing. I compiled both programs in terminal fine but not sure which one should I be running first or do they need to be started simultaneously?
Thanks
Your server is running in a infinite loop. Avoid that.
You have to restart your computer.
while (true)
{
line = is.readLine();
os.println(line);
}
try
while (!line.equals("Hello Server!"))
{
line = is.readLine();
os.println(line);
}
Run the server first. echoServer.accept(); waits for a connection. When it gets the first connection,
http://docs.oracle.com/javase/tutorial/networking/sockets/ this is a short java tutorial on how to work with sockets and also you can learn how to make a server that would accept multiple connections at a time. This tutorial explains you always need to start the server first, which is only logical. You should use threads to manage connections and then close them so that you use resources efficiently
Related
I am using sockets in JAVA and I have 3 Servers that are Clients are the same time. I want them to exchange some information.
This is what I want to create:
The input should be something like this:
Server started at:/172.16.2.22:8080
info for first,
info for second,
info for third,
Server started at:/172.16.2.22:8081
info for first,
info for second,
info for third,
Server started at:/172.16.2.22:8082
info for first,
info for second,
info for third,
But for some reason it shows only the info of the client that is currently a server as well.
So I get this result:
Server started at:/172.16.2.22:8080
info for first
Server started at:/172.16.2.22:8081
info for second
Server started at:/172.16.2.22:8082
info for third
This is how I initiate my code, the Server:
private void startServer() {
ServerSocket providerSocket = null;
BufferedReader in = null;
try {
InetAddress addr = InetAddress.getByName(this.serv.getIP());
providerSocket = new ServerSocket(this.serv.getPort(), 50, addr);
System.out.println("ServThread started at:" + addr + ":" + this.serv.getPort());
// create a new thread object
Thread t = new ClientHandler(providerSocket);
// Invoking the start() method
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
This is the ClientHandler that I am using for threads:
class ClientHandler extends Thread {
final ServerSocket s;
// Constructor
public ClientHandler(ServerSocket s) {
this.s = s;
}
public void run() {
Socket s = null;
try {
s = this.s.accept();
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
// receive the answer from client
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
And finally my Clients, that are also the servers. I am using a for loop to read a txt with all the IP,PORTS of my servers:
private void startSender() {
for (MyServers servs : ServersTXT.fetchTXTofServers()) {
BufferedWriter out;
try (Socket s = new Socket(servs .getIP(), servs .getPort())) {
out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
out.write(servs.info());
out.newLine();
out.flush();
} catch (ConnectException err) {
// Connection failed because not all servers on the txt are up
} catch (IOException e) {
e.printStackTrace();
}
}
}
I took some time to understand your architecture and I managed to figure out which was the problem. The ClientHandler is indeed wrong because the connection.accept() part is outside the while loop and the connections get lost. The architecture you are trying to achieve has the following rule. Once I get a connection, spawn a thread to handle this connection not just for one time, but continuously. The above code is going to fix your problem as long as you place it inside the run function at the ClientHandler thread.
ServerSocket providerSocket;
Socket connection;
InetAddress addr;
try {
addr = InetAddress.getByName(this.broker.getIP());
providerSocket = new ServerSocket(this.broker.getPort(), 50, addr);
while (true) {
connection = providerSocket.accept();
ObjectOutputStream out = new ObjectOutputStream(connection.getOutputStream());
ObjectInputStream in = new ObjectInputStream(connection.getInputStream());
System.out.println(n.readUTF());
in.close();
out.close();
connection.close();
}
} catch (Exception err) {
err.printStackTrace();
}
Also, at the sender part, at the try block, you try to execute the code at parenthesis, usually try blocks have no parentheses, in my code I removed it.
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.
Hey guys I'm trying to write a simple socket program that basically send like a "Hello" message from client and then server gets and print its out.
I'm trying to follow this guide: http://www.javaworld.com/jw-12-1996/jw-12-sockets.html?page=4
However when i try to instantiate serverSocket with port number it causes syntax error that advises to either remove the argument or create a new constructor for that method. It also doesn't recognize accept() method when I try to use it. Anyone know why this is happening?
Here is my Client code:
public static void main(String[] args) throws UnknownHostException, IOException
{
Socket testSocket = null;
DataOutputStream os = null;
DataInputStream is = null;
try
{
testSocket = new Socket("192.168.0.104", 5932);
os = new DataOutputStream(testSocket.getOutputStream());
is = new DataInputStream(testSocket.getInputStream());
}
catch (UnknownHostException e)
{
System.err.println("Couldn't find Host");
}
catch (IOException e)
{
System.err.println("Couldn't get I/O connection");
}
if (testSocket != null && os != null && is != null)
{
try
{
os.writeBytes("Hello Server!\n");
os.close();
is.close();
testSocket.close();
}
catch (UnknownHostException e)
{
System.err.println("Host not found");
}
catch (IOException e)
{
System.err.println("I/O Error");
}
}
}
Here is my Server Code (UPDATED):
public static void main(String[] args)
{
String line = new String() ;
try
{
ServerSocket echoServer = new ServerSocket(5932);
Socket clientSocket = echoServer.accept();
DataInputStream is = new DataInputStream(clientSocket.getInputStream());
PrintStream os = new PrintStream(clientSocket.getOutputStream());
while (true) {
line = is.readLine();
os.println(line);
}
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
}
Here are actual screenshots.
Error1: http://i.imgur.com/8JIOd.png
Error2: http://i.imgur.com/7uCow.png
Your class is named ServerSocket. It doesn't have a constructor that takes an int. Name your class something else so it doesn't conflict with java.net.ServerSocket.
Either that use the absolute path
java.net.ServerSocket clientSocket = new java.net.ServerSocket(5932)
You have not posted import statements. Classes ServerSocket, Socket etc belong to package java.net. Double check that you have import statements in the beginning of your class.
something like import java.net*. Or, better use IDE to help you. Ctrl-Shift-O in Eclipse will do the work.
Try it this way....
- First check that you have properly imported the package java.net.*
public static void main(String[] args)
{
String line = new String() ;
try
{
ServerSocket echoServer = new ServerSocket(5932);
Socket clientSocket = echoServer.accept();
DataInputStream is = new DataInputStream(clientSocket.getInputStream());
PrintStream os = new PrintStream(clientSocket.getOutputStream());
while (true) {
line = is.readLine();
os.println(line);
}
}
catch (IOException e)
{
System.out
}
}
EDIT BASED ON SCREEN SHOTS:
The class you defined is named ServerSocket. This is hiding the actual class you are trying to use. Your class does not implement a constructor that takes an int and does not define accept(), these are the errors you are receiving. You should not name your class the same name as another existing class as it leads to these types of errors and further confusion.
ORIGINAL:
You have an syntax error when you handle the exception thrown by the ServerSocket.
try
{
echoServer = new ServerSocket(5932);
}
catch (IOException e)
{
System.out
}
It looks like you are missing .println(e); from the end of the last line.
I am trying to write a client-server system using Sockets in java, however I cannot seem to read data sent from the server to the client.
Here is the code for the client:
public class ClientSocket
{
Socket clientSocket = null;
PrintWriter out = null;
BufferedReader in = null;
// establish a connection to All Care's server application through socket 4444 (adjust localhost to reflect the IP address that the server
// is being run from)
public ClientSocket()
{
try
{
clientSocket = new Socket("localhost", 4445);
out = new PrintWriter(clientSocket.getOutputStream());
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
}
catch (IOException e)
{
System.out.println("Could not connect to All Care Server Application");
}
}
public void closeClientSocket()
{
try
{
clientSocket.close();
}
catch (IOException e)
{
System.out.println("Could not close connection to All Care Server Application");
}
}
public String getMessageFromServer()
{
try
{
String input = in.readLine();
return input;
}
catch (IOException e)
{
System.out.println("Could not read message from server");
}
return "No Data";
}
public void sendMessageToServer(String message)
{
out.write(message);
}
}
And here is the Server code:
public class ArFileServer {
public static void main(String[] args)
{
ServerSocket serverSocket = null;
boolean listening = true;
try
{
serverSocket = new ServerSocket(4445);
// infinite loop to continually listen for connection requests made by clients
while (listening)
{
new ClientConnection(serverSocket.accept()).start();
if (serverSocket != null)
{
System.out.println("Connection to client established");
}
}
serverSocket.close();
}
catch (IOException e)
{
System.out.println("Error could not create socket connection to port");
}
}
}
public class ClientConnection extends Thread
{
private Socket socket = null;
public ClientConnection(Socket socket)
{
super("ClientConnection");
this.socket = socket;
}
// the thread that runs after a connection to the server has been accepted
#Override
public void run()
{
try
{
PrintWriter out = new PrintWriter(socket.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
sendMessagetoClient(out, "CONNECTION SUCCESS");
// check login credentials sent from client to the server
// if valid send back their encrypted password, otherwise output a login error message
// wait for user input and then do various processes based on their requests
in.close();
out.close();
socket.close();
}
catch (IOException e)
{
System.out.println("Client socket connection error");
}
}
// sends a message to the client
void sendMessagetoClient(PrintWriter out, String message)
{
out.write(message);
}
// listens for a message from the client
String getMessageFromClient(BufferedReader in)
{
try
{
String input = in.readLine();
return input;
}
catch (IOException e)
{
System.out.println("Could not read message from client");
}
return "No Data";
}
And here is the line of code im using to see if the data is being sent.
System.out.println(clientSocket.getMessageFromServer());
In your sendMessageToClient() method, you need to flush:
void sendMessagetoClient(PrintWriter out, String message)
{
out.write(message);
out.flush();
}
Or, when you create the PrintWriter, use the constructor with autoflush:
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
And when you write, instead of out.write(message) use printf() or println().
There are several problems here.
You are reading lines but you aren't writing lines.
You aren't checking the result of readLine() for null, which means the peer has closed the connection, which means you must do likewise.
You aren't flushing the PrintWriter after you write.
You are closing things in the wrong order. You must close the output writer/stream you have attached to the socket. Doing that flushes it and then closes the input stream/reader and the socket. Doing this in the wrong order loses the flush. Once you've closed the output you don't need the other two closes.
You are using PrintWriter, which swallows exceptions, across a network, where you need to know about exceptions and errors in communication, and you aren't checking for errors either. Use a BufferedWriter.
in the clint code you are not connecting with server socket.
for clint socket connection
socket soc= new socket ("server host ip",port);
I am making a prototype client & server so that I can understand how to handle reconnects.
The server ought to create a serversocket and listen forever. A client may connect, send its data, and close its socket but it will not send a "I'm done and closing" type message to the server. For this reason, the server gets a EOFException when it does a readByte() since the remote client has closed. In the error handler for the EOFException, it will close the socket and open a new one.
Here's the problem: The client sometimes gets a SocketWriteError when it does the outputStream.write() call even after it successfully opens the socket/inputstream/outpustream. It may have something to do with the frequency that I'm opening and closing these sockets. One interesting thing is that the client does an arbitrary number of writes/close/reconnects before crapping out. It will sometimes crap out on the first reconnect, other times it will take 50 reconnects before seeing the SocketWriteError.
Here's the error on the client side:
java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:115)
at bytebuffertest.Client.main(Client.java:37)
Here are some snippets of code:
SERVER:
public static void main(String[] args)
{
Server x = new Server();
x.initialize();
}
private void initialize()
{
ServerSocket s;
InputStream is;
DataInputStream dis;
while (true) //ADDED THIS!!!!!!!!!!!!!!!!!!!!!!
{
try
{
s = new ServerSocket(4448);
s.setSoTimeout(0);
s.setReuseAddress(true);
is = s.accept().getInputStream();
System.out.println("accepted client");
dis = new DataInputStream(is);
try
{
byte input = dis.readByte();
System.out.println("read: " + input);
} catch (Exception ex)
{
System.out.println("Exception");
dis.close();
is.close();
s.close();
}
} catch (IOException ex)
{
System.out.println("ioexception");
}
}
}
CLIENT:
public static void main(String[] args)
{
Socket s;
OutputStream os;
try
{
s = new Socket("localhost", 4448);
s.setKeepAlive(true);
s.setReuseAddress(true);
os = s.getOutputStream();
int counter = 0;
while (true)
{
try
{
os.write((byte) counter++);
os.flush();
os.close();
s.close();
s = new Socket("localhost", 4448);
s.setKeepAlive(true);
s.setReuseAddress(true);
os = s.getOutputStream();
} catch (Exception e)
{
e.printStackTrace();
System.err.println("ERROR: reconnecting...");
}
}
} catch (Exception ex)
{
ex.printStackTrace();
System.err.println("ERROR: could not connect");
}
}
Does anyone know how to properly reconnect?
Don't close the ServerSocket on an error, just .accept() a new connection.
What I normally do is each time ServerSocket.accept() returns a Socket, I spawn off a thread to handle sending and receiving from that Socket. That way you're ready to start accepting a new connection as soon as somebody wants to connect to you.