I'm trying to write an android app that interacts with a server. I'm trying now to write the server side with sockets. I created an instance of ec2 and ran it. I connected to it with putty and ran a simple "hello world" java program. Now I'm trying to run a server which use a socket, but I get this as the server socket: ServerSocket[addr=0.0.0.0/0.0.0.0,localport=5667].
This is my code, very basic so far:
public class EchoServer {
public static void main(String[] args) throws IOException {
int portNumber = 5667;
System.out.println("server socket main");
try (ServerSocket serverSocket = new ServerSocket(portNumber);
) {
System.out.println(serverSocket.toString());
} catch (IOException e) {
System.out
.println("Exception caught when trying to listen on port "
+ portNumber + " or listening for a connection");
System.out.println(e.getMessage());
}
}
}
What should I do to run the server so I could connect to it via my andriod device?
Thanks!
You are on the right track. 0.0.0.0 simply means:
A way to specify "any IPv4-interface at all". It is used in this way when configuring servers (i.e. when binding listening sockets).
Next, your server will need to listen for incoming connections by using SocketServer.accept().
And then of course you'll want to receive and send data on the socket. This tutorial should help.
Finally, if you plan on serving multiple clients simultaneously with your server, you will want to consider concurrency and scalability, and perhaps consider using a framework like Netty.
Related
I am currently trying to make an application that will send messages to a server using one port, but will receive messages on another port. However, based on tutorials I have followed, it looks like the act of connecting to the server is where ports come into play and my client is receiving and sending messages on the same port. How do I make it so it sends on one port but receives on the other?
Here is the code that I think is relevant from the client side (I put some stuff that seems unrelated because I think they are things that would be altered by receiving on one port but sending on another, and ignore the comment about replacing inetaddress, that is just me working on implementing this in a gui):
public void startRunning(){
try{
connectToServer();
setupStreams();
whileChatting();
}catch(EOFException eofException){
showMessage("\n Client terminated connection");
}catch(IOException ioException){
ioException.printStackTrace();
}finally{
closeStuff();
}
}
//connect to server
private void connectToServer() throws IOException{
showMessage("Attempting connection... \n");
connection = new Socket(InetAddress.getByName(serverIP), 480);//replace serverIP with ipTextField.getText or set serverIP to equal ipTextField.getText? Same with port number.
showMessage("Connected to: " + connection.getInetAddress().getHostName() );
}
//set up streams to send and receive messages
private void setupStreams() throws IOException{
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
showMessage("\n Streams are good! \n");
}
//while talking with server
private void whileChatting() throws IOException{
ableToType(true);
do{
try{
message = (String) input.readObject();
showMessage("\n" + message);
}catch(ClassNotFoundException classNotfoundException){
showMessage("\n Don't know that object type");
}
}while(!message.equals("SERVER - END"));
}
//send messages to server
private void sendMessage(String message){
try{
output.writeObject("CLIENT - " + message);
output.flush();
showMessage("\nCLIENT - " + message);
}catch(IOException ioException){
messageWindow.append("\n something messed up ");
}
}
//change/update message window
private void showMessage(final String m){
SwingUtilities.invokeLater(
new Runnable(){
public void run(){
messageWindow.append(m);
}
}
);
}
EDIT/UPDATE: To help clarify some things, here is some more information. The device that sends the first message is connected to a sensor, and it sends information when that sensor detects something to the other device. The receiving device sends a message back on a different port telling the original sending device how to respond. Lets name these two devices the "reporter-action taker" and the "decision maker-commander".
If you want to use TCP/IP sockets you can't use a a socket to send and another to read. That's not what they are for.
If you use a centralized distributed algorithm (server/client communication) you have to set the server to listen on a single socket port with the ServerSocket class: then the server tries to accept clients through that socket.
Example:
ServerSocket listener = new ServerSocket(Port)
While (true) {
new Clienthandler(listener.accept());
}
The server will listen on that port, and when a client tries to connect to that port if it is accepted the server launches its handler. On this handler constructor the Socket object used on the client is received on an argument and can then be used to get the writers and the readers. The reader on this handler class will be the writer on the client class and vice-versa, maybe that's what you were looking for.
Your question about using two ports in this manner is a bit strange. You state that you have a client and a server and that they should communicate on different ports.
Just to clarify picture the server as a hanging rack for jackets with several hooks in a row. Each port the server listened on represents a hook. When it comes to the client server relationship the client or jacket knows where to find its hook, however the hook is blind and have no idea where to find jackets.
Now, the client selects a port or a hook and connects to it. The connection is like a pipeline with two pipes. One for the client to deliver data to the server with and the other to send data from the server back to the client. When the connection is established data can be transferred both ways. This means that we only need one port open on the server to send data both from the client to the server and in the opposite direction.
The reason for only having one open port open on the server for the clients to connect to is that holding an open port for connections is hard to do on a regular client computer. The normal desktop user will be behind several firewalls blocking incoming connections. If that wasn't the case the client would probably be hacked senseless from malicious viruses.
Moving on with the two port solution we could not call this a client server connection per say. It would be more like a peer to peer connection or something like that. But if this is what you want to do, the application connecting first would have to start by telling the other application what ip and port to use for connecting back, it should probably also want to give some kind of token that are to be used to pair the new incoming connection when connecting back.
You should take note that making such an implementation is not a good idea most of the time as it complicates things a whole lot for simple data transfer between a client and server application.
We want to capture the data which comes to the system on port say 7777.
public static void main(String[] args) {
try {
final ServerSocket serverSocket = new ServerSocket(7777);
new Thread("Device Listener") {
public void run() {
try {
System.out.println("Listener Running . . .");
Socket socket = null;
while ((socket = serverSocket.accept()) != null) {
System.out.println("| Incoming : "+ socket.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
We have a device which sends data to the port 7777, which comes with a native windows application. The windows native application is receiving data which comes from that device. We have to receive that data on port 7777 through our java project.
In the above code,
The java server socket is created but no incoming connections are received from the device.
The java server socket is receiving connections from telnet command.
The data format which is used by the device and the other native application may be different, but atleast it has to be connected from java server socket. is it correct?
how to receive the data which is transmitted to port 7777.
EDIT:
Ok, the data is received with UDP socket. it is 68 in length. The device documentation doesn't specify any methods to capture this data, because may be it is designed to work with the specified application. We can't contact the manufacturer also. is there any way (if possible) to know the format of incoming bytes. we have tried network sniffers but we cant understand the format.
If you're receiving from the telnet command, then I suspect you have a network-specific issue.
your device isn't talking to the same ip address / hostname that you're configuring telnet with
you have a routing or firewall issue
is your device possibly using UDP rather than TCP ?
The java server socket is created but no incoming connections are received from the device.
So either there is a firewall in the way or the device isn't trying to connect to that port.
The java server socket is receiving connections from telnet command.
So the Java application is listening to that port.
The data format which is used by the device and the other native application may be different, but at least it has to be connected from java server socket. is it correct?
Yes.
how to receive the data which is transmitted to port 7777.
First you have to accept the connection. On the evidence here the device isn't connecting to port 7777 at all. I suggest some network sniffing is in order to see what it really is doing.
Right now I have a Server.java script that is waiting to establish a connection with a listening port. It is currently running on my Amazon instance.
I also have a Client.java file that is trying to send data to the server that is running locally.
Currently the problem is (and if you know about Amazon cloud you know this) the amazon Ubuntu instance requires a private key to confirm the RSA authentication. Is there someway to do this with the socket? I looked at the constructor and could not find anything to give another argument for the key.
to SSH I have to do this i.e. : ssh -i key.pem root#server.amazonaws.com
Client. java
import java.io.PrintWriter;
import java.net.Socket;
class Client {
public static void main(String args[]) {
String data = "toobie ornaught toobie";
try {
Socket skt = new Socket("my ubuntu instance", 1235);
System.out.print("Server has connected!\n");
PrintWriter out = new PrintWriter(skt.getOutputStream(), true);
System.out.print("Sending string: '" + data + "'\n");
out.print(data);
out.close();
skt.close();
} catch (Exception e) {
System.out.print("Whoops! It didn't work!\n");
}
}
}
You are confused. TCP sockets have nothing to do with ssh (except that ssh does use a TCP socket). RSA keys are needed for SSH. You are just opening a plain TCP socket. The keys and other authentication stuff do not apply.
What you need to do is allow your port number through the firewall which is automatically running on EC2 instances.
I created a simple echo server in Java. When I try it locally, it works as it should. However, when I try to connect it from a different computer using the IP address and the port number the server is running on, it never connects. Is there anything else that should be done to connect to a server from a different computer?
import java.net.Socket;
import java.net.ServerSocket;
public class EchoServer {
public static void main(String[] args) throws Exception {
// create socket
int port = 4444;
ServerSocket serverSocket = new ServerSocket(port);
System.err.println("Started server on port " + port);
// repeatedly wait for connections, and process
while (true) {
// a "blocking" call which waits until a connection is requested
Socket clientSocket = serverSocket.accept();
System.err.println("Accepted connection from client");
// open up IO streams
In in = new In (clientSocket);
Out out = new Out(clientSocket);
// waits for data and reads it in until connection dies
// readLine() blocks until the server receives a new line from client
String s;
while ((s = in.readLine()) != null) {
out.println(s);
}
// close IO streams, then socket
System.err.println("Closing connection with client");
out.close();
in.close();
clientSocket.close();
}
}
}
Please check the following things.
Is the server computer behind a network proxy ?
Does it have an independent public IP Address by which it is accessible from
anywhere ? Or, does it have an internal IP, by which it can be accessed in your LAN ?
Make sure FireWalls has an exception for port 4444. Or you may turn it of in both client and server.
If it does not help, post the exception you are getting (by editing the question). Or the server program is just freezing without any error ?
If this is on your LAN refer to the machine running your EchoServer by name (the actual machine name, I believe they show you to do it this way on the Sun Tutorial that posted this echo server excercise correct?). If that works it would help a lot in troubleshooting the issue.
HOST
First, my host is dreamhost. I have root access. The system is a linux system.
SERVER
**UPDATE: It looks like the server uses modsecurity (modsecurity.org). I'll look into it more now, but if anyone has any tips or knows how to work with it, that's where I'm stuck now. **
Second, I wrote a java server that binds to port #### and the listens for connections. I can run this local & connect, but I'm trying to put it up on my server and connect from anywhere. That is the idea behind a server.
private int port;
private ServerSocketChannel ssc;
private Selector selector;
public Server(int port) {
this.port = port;
}
public void run() {
try {
ssc = ServerSocketChannel.open();
selector = Selector.open();
ssc.socket().bind((new InetSocketAddress(port)));
new Thread(new ReadLoop(selector)).start();
new Thread(new AcceptingLoop(ssc, selector)).start();
System.out.println("Bound to port " + port + " and awake:");
} catch (IOException e) {
System.out.println("Server could not start.");
e.printStackTrace();
}
}
I launched this on the server. The program says it successfully bound to the port.
CLIENT
The client is flash, AS3. Here's the code i use to attempt the connect:
var mySocket:XMLSocket = new XMLSocket();
mySocket.connect("http://mydomain.net", ####);
I'm well aware of the sandbox policies. This is something else. I receive this error:
IOERROR [IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2031: Socket Error. URL: http:--mydomain.net"] (replace -- with //, stackoverflow was reading it as a link)
This error apparently means that Flash never found a server. I would have gotten a security error if it had been the sandbox.
Anyway, how do I tell if ports are open correctly, if they are blocked, etc?
I'm also wondering if this has something to do with it:
http://wiki.dreamhost.com/Mod_security
I unfortunately don't understand a lot of this stuff, but I'm trying to learn.
Try and run your server program on a port that is unlikely to be blocked (e.g. 80, 443). Of course, make sure that nothing else is using the port that you choose.