I'm trying to learn about client/server and sockets right now but I'm confused on the bigger scope of things. I followed a tutorial that has a client as an android app and the server is a java application. I run both of them on eclipse fine.
My question now is how do I make this global? So I'll take my server code written in java, export it to a text called server.java, and then upload it to my personal site? And then when I start my client android app, I'll make a call to say http://blah.com/server.java to start my server, right? Then my server will begin listening on that port and my client can connect to it?
Server:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class SimpleTextServer {
private static ServerSocket serverSocket;
private static Socket clientSocket;
private static InputStreamReader inputStreamReader;
private static BufferedReader bufferedReader;
private static String message;
public static void main(String[] args) {
try {
serverSocket = new ServerSocket(4444); // Server socket
} catch (IOException e) {
System.out.println("Could not listen on port: 4444");
}
System.out.println("Server started. Listening to the port 4444");
while (true) {
try {
clientSocket = serverSocket.accept(); // accept the client connection
inputStreamReader = new InputStreamReader(clientSocket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader); // get the client message
message = bufferedReader.readLine();
System.out.println(message);
//will later add an output stream to write back to android
inputStreamReader.close();
clientSocket.close();
} catch (IOException ex) {
System.out.println("Problem in message reading");
}
}
}
}
Related
I'm new to socket programming/networking in general. I'm trying to create a simple IRC that's an echo server. I'm using 127.0.0.1 and port 8080 for my socket object but I keep getting a ConnectionException. Does it have to do with me not setting anything up on my computer to allow connections?
Client class (I need to make a Server class maybe that handles allowing connections?)
package client.build;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.*;
import java.util.Scanner;
public class Client {
private static Socket socket;
private static DataInputStream inputStream;
private static DataOutputStream outputStream;
// This might not be needed
private static Scanner input = new Scanner(System.in);
private final String[] arguments;
public Client(String[] arguments) throws IOException {
this.arguments = arguments;
}
public void connect() throws IOException, InterruptedException {
try {
socket = new Socket(arguments[0], Integer.parseInt(arguments[1]));
inputStream = new DataInputStream(System.in);
outputStream = new DataOutputStream(socket.getOutputStream());
} catch(ConnectException e) {
System.out.println("failed to connect to echo server");
Thread.sleep(600);
System.exit(0);
}
}
}
Few things to check:
You are trying to create echo server, which means that you need to listen on 8080 instead of connecting to 8080?
ServerSocket serverSocket = new ServerSocket(8080);
Socket clientSocket = serverSocket.accept();
Assuming that your code is actually the IRC client. Do you have something that listens on port 8080 on 127.0.0.1? Try using netstat to verify that it is listening on 127.0.0.1:8080
Check that arguments[0] is really 127.0.0.1. You can try with the null for localhost
I started working with sockets this week and I'm having a hard time.
My goal is when the client sent a message the server responded with a notification.
On the client side sending to the server has no problem, but when the server sends to the client nothing appears.
Can anybody help me with this problem?
Client:
Thread thread = new Thread(new myServerThread());
thread.start();
class myServerThread implements Runnable {
Socket socket;
ServerSocket serverSocket;
InputStreamReader inputStreamReader;
BufferedReader bufferedReader;
String message;
Handler handler = new Handler();
#Override
public void run() {
try {
serverSocket = new ServerSocket(5000);
while (true){
socket = serverSocket.accept();
inputStreamReader = new InputStreamReader(socket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader);
message = bufferedReader.readLine();
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), message,Toast.LENGTH_LONG).show();
}
});
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
SERVER:
String EMAIL = "Email";
try {
serverSocket = new ServerSocket(6000);
while(true){
socket = serverSocket.accept();
inputStreamReader = new InputStreamReader(socket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader);
email = bufferedReader.readLine();
System.out.println(email);
if(email.equals(EMAIL)){
jTextArea1.setText(email);
try {
socket = new Socket("localHost", 5000);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
printWriter.write(message);
printWriter.flush();
printWriter.close();
System.out.println("connected");
} catch (IOException e) {
e.printStackTrace();
}
}else{
}
}
} catch (IOException ex) {
}
etEmail = findViewById(R.id.etvEmail);
First the short answer: Your Java codes are both working almost fine.
Anyway, you should always test your application against another program that is known to be OK. By testing one self-written program against another fresh self-written program, it is difficult to say which of both is broken. It seems that you are testing it with some GUI (Android?). Transforming the relevant part to a simple console application which you run on a regular PC makes troubleshooting much easier.
So let me show how I checked your code on my Linux laptop:
First copy your "client" code into a "Hello-World" template. I added some debug messages and a loop which allows the client to receive more than one single line of text:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
class Main
{
static class myServerThread implements Runnable
{
Socket socket;
ServerSocket serverSocket;
InputStreamReader inputStreamReader;
BufferedReader bufferedReader;
String message;
#Override
public void run()
{
try
{
serverSocket = new ServerSocket(5000);
while (true)
{
System.out.println("Accepting...");
socket = serverSocket.accept();
System.out.println("Connected...");
inputStreamReader = new InputStreamReader(socket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader);
String message = bufferedReader.readLine();
while (message!=null)
{
System.out.println("Received:" + message);
message = bufferedReader.readLine();
}
System.out.println("Closing...");
socket.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
public static void main(String[] args)
{
Thread thread = new Thread(new myServerThread());
thread.start();
}
}
I started the "client" and opened another command window to open a network connection with Netcat and send two lines of text:
nc localhost 5000
Hallo
Test
The related output of the "client" program was:
Accepting...
Connected...
Received:Hallo
Received:Test
Closing...
Accepting...
So the "client" part is running fine obviously.
Next I copied your "server" code into a "Hello World" template:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
class Main
{
static class myServerThread implements Runnable
{
Socket socket;
ServerSocket serverSocket;
InputStreamReader inputStreamReader;
BufferedReader bufferedReader;
String message;
#Override
public void run()
{
String EMAIL = "Email";
try
{
serverSocket = new ServerSocket(6000);
while (true)
{
System.out.println("Accepting...");
socket = serverSocket.accept();
System.out.println("Connected...");
inputStreamReader = new InputStreamReader(socket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader);
String message = bufferedReader.readLine();
while (message != null)
{
System.out.println("Received:" + message);
if (message.equals(EMAIL))
{
System.out.println("Sending...");
try
{
socket = new Socket("localHost", 5000);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
printWriter.write(message);
printWriter.flush();
printWriter.close();
System.out.println("sending done");
}
catch (IOException e)
{
e.printStackTrace();
}
}
message = bufferedReader.readLine();
}
System.out.println("Closing...");
socket.close();
}
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
}
public static void main(String[] args)
{
Thread thread = new Thread(new myServerThread());
thread.start();
}
}
Again I added some debug messages and a loop, so the server can receive multiple lines of text. Since this Java program handles two connections, I had to open two command windows.
In the first command window I tell NetCat to accept (listen) connection on port 5000. That is where your "server" will send the "Email" message to:
nc -lp 5000
In the second command window I tell Netcat to connect to your "server" on port 6000, then I send two lines of text and then I press Ctrl-C to stop it:
nc localhost 6000
Test
Email
^C
The related output of the "server" program is:
Accepting...
Connected...
Received:Test
Received:Email
Sending...
sending done
Closing...
Accepting...
And my listening Netcat in the other (first) command windows produced this output:
stefan#stefanpc:/hdd/stefan$ nc -lp 5000
Emailstefan#stefanpc:/hdd/stefan$
So everything looks fine on my machine. Beside one small detail: There is no line break after the "Email" that your "server" sends to the client (in this case NetCat). So the fix is simple:
printWriter.write(message+"\n");
This final line break is required because your client consumes the input by readLine().
NetCat is a very helpful tool to test plain text TCP socket communication. It is included in all Linux distributions. If you have difficulties to find a Windows executable, then take it from my homepage: http://stefanfrings.de/avr_tools/netcat-win32-1.12.zip
Please comment if that was helpful to you.
Client Class
import java.io.PrintWriter;
import java.net.Socket;
public class Client
{
public static void main(String[] args)
{
try
{
System.out.println(" Starting Client ");
Socket socket = new Socket ("localhost",55555);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(),true);
printWriter.println("Hello from client");
printWriter.println("Conected, Yes!");
socket.close();// Changes as suggested by Jack
}
catch (Exception e)
{
System.out.println(e);
}
}
}
Server Class
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class Server
{
public static void main(String[] args)
{
System.out.println(" inside main ");
try
{
System.out.println("Starting Server");
ServerSocket serverSocket= new ServerSocket(55555);
Socket clientSocket = serverSocket.accept();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine;
while ((inputLine= bufferedReader.readLine())!=null)
System.out.println("Server Message:"+inputLine);
}
catch (IOException e)
{
System.out.println("IOException "+e);
}
}
}
Output:
Starting Server
Server Message:Hello from client
Server Message:Conected, Yes!
IOException java.net.SocketException: Connection reset
Client and Server java files are in the same package.
What would trigger IOException in the following code?
Is it something to do with Eclipse?
FYI, I am using Eclipse SDK
Version: 4.2.2
Build id: M20130204-1200
The problem is that your client opens a Socket, sends some data and then exits the program, thus abruptly closing the connection.
You should call close() on the Socket from the client side to notify the server that the socket it is going to be closed.
As #Jack mentioned in his answer you need to close() your socket before the client application exit.
Socket is AutoCloseable
The safe way of work with closable resource is creation in try block:
public class Client {
public static void main(String[] args) {
System.out.println(" Starting Client ");
try(Socket socket = new Socket("localhost", 55555)) {
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.println("Hello from client");
printWriter.println("Conected, Yes!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
and it will be closed automatically on exit (from try section).
I am trying to connect a client application to my code through port 8000 on my pc offline. I am using the ServerSocket library to connect using the below code. The client's application sends XML messages across the port and I need to connect, interpret and respond. (Please bear in mind that I haven't coded interpret/respond yet when reading the below).
Every time I try to send a message from the client application (when running the debug feature in eclipse), the code gets to the serverSocket.accept() method which should be the 'handshake' between client and server and can't go any further. I am unable to change the client application obviously so need to figure out why it's not accepting the connection.
package connect;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class PortListener2 {
public static void main(String[] args){
System.out.println("> Start");
int portNumber = 8000;
try (
ServerSocket serverSocket =
new ServerSocket(portNumber);
Socket clientSocket = serverSocket.accept();
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
) {
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("Received: "+inputLine);
out.println(inputLine);
if (inputLine.equals("exit")){
break;
}
}
} catch (Exception e) {
System.out.println("Exception caught when trying to listen on port "
+ portNumber + " or listening for a connection");
System.out.println(e.getMessage());
e.printStackTrace();
} finally {
System.out.println("Disconnected");
}
}
}
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.