I am writing an app which needs to receive a string from a server. The following code works if the IP Adress connected to is "127.0.0.1" (The Client and the server are on the same phone, just for testing purpose), but not if it is the "real" IP Adress of the phone.
Server:
ServerSocket echoServer = null;
String line;
DataInputStream is;
PrintStream os;
Socket clientSocket = null;
// Try to open a server socket on port 9999
try {
echoServer = new ServerSocket(1109);
} catch (IOException e) {
System.out.println(e);
}
// Create a socket object from the ServerSocket to listen and
// accept
// connections.
// Open input and output streams
try {
clientSocket = echoServer.accept();
is = new DataInputStream(clientSocket.getInputStream());
os = new PrintStream(clientSocket.getOutputStream());
// As long as we receive data, echo that data back to the
// client.
os.println("Das ist ein Test immernoch");
publish("Fertig");
} catch (IOException e) {
publish("Fertig");
} catch (Exception e) {
publish("Fertig");
}
Client:
Socket smtpSocket = null;
DataOutputStream os = null;
DataInputStream is = null;
try {
smtpSocket = new Socket();
smtpSocket.connect(new InetSocketAddress("46.114.153.58", 1109), 10000); //That is the critcal line, if the IP is "127.0.0.1" everything works perfectly fine
os = new DataOutputStream(smtpSocket.getOutputStream());
is = new DataInputStream(smtpSocket.getInputStream());
} catch (UnknownHostException e) {
return "Fehler";
} catch (IOException e) {
return "Fehler";
}
if (smtpSocket != null && os != null && is != null) {
try {
os.writeBytes("HELO\n");
String s = is.readLine();
os.close();
is.close();
smtpSocket.close();
return s;
} catch (UnknownHostException e) {
//System.err.println("Trying to connect to unknown host: " + e);
} catch (IOException e) {
//System.err.println("IOException: " + e);
}
}
return "Fehler";
}
EDIT: Hence this is an app for a mobile device, there is no router I can configure.
Add this to your code
if (Build.VERSION.SDK_INT >= 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
}
You might have to forward the port you are using on your router if you are planning on using ServerSocket with external connections.
If this is the ip address of your router and you are connecting your android mobile to the router through wifi , then you have to port forward the port 1109 in your router to your mobile.
If this is the ip address of your android mobile connected through data connection , then there will be some restrictions on your data provider blocking ports for security .
46.114.153.58 is this a static ip address or dynamic ?
If its a dynamic ip address , first check the availability of the ip address by pinging it.
Related
Trying to connect to my own POP3 server on localhost(1024 port). Its code:
server_socket = new ServerSocket(SBAP_PORT);
Socket clntSocket = server_socket.accept();
public void run() {
try {
try {
in = new BufferedReader(
new InputStreamReader(socket.getInputStream()
));
out = new PrintWriter(socket.getOutputStream(), true);
out.print("+OK\\r\\n");
command = in.readLine();
String result = handleInput(command);
out.println(result);
} finally {
socket.close();
state.close();
System.out.println("client offline.");
}
} catch (Exception ignored) {
}
}
It's working fine with telnet, but when I try to do it with Thunderbird, just get timeout(Failed to find settings for your email account).
In debug I see, that I get null string while connecting.
What am I doing wrong? Maybe I should send something to client just after connecting?
I think it must be \r\n rather \\r\\n, plus try to flush for each response you send to the client by out.flush();, but it might not be necessary.
I'm having problems when creating a socket in android. I'm using LibGDX.
#Override
public void create() {
System.out.println("Enter IP adress.");
ip = "78.61.65.198";
System.out.println("Connecting...");
socket = connection(PORT, ip);
System.out.println("Setting up InputStream");
reader = reader(socket);
System.out.println("Setting up OutputStream");
output = output(socket);
while (socket.isConnected()) {
output.println("0;" + Gdx.input.getAccelerometerX() + ";" + Gdx.input.getAccelerometerY());
}
}
public static Socket connection(int port, String ip) {
try {
return new Socket(InetAddress.getByName(ip), port);
} catch (UnknownHostException e) {
e.printStackTrace();
System.out.println("Unknown host...");
return null;
} catch (IOException e) {
e.printStackTrace();
System.out.println("Failed to connect...");
return null;
}
}
public static BufferedReader reader(Socket socket) {
try {
return new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
System.err.println("Couldn't get inputStream...");
e.printStackTrace();
return null;
}
}
public static PrintStream output(Socket socket) {
try {
return new PrintStream(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
System.err.println("Couldn't get outputStream");
return null;
}
}
Server:
#Override
public void create() {
System.out.println("Creating server...");
server = hostServer(PORT);
System.out.println("Waiting for Client 1...");
client1 = waitForConnections(server);
System.out.println("Setting up input/output for client 1...");
client1Input = reader(client1);
client1Output = output(client1);
setScreen(new gameScreen(this));
}
public static ServerSocket hostServer(int port){
try {
return new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
System.err.println("Failed to host server!");
return null;
}
}
public static BufferedReader reader(Socket socket){
try {
return new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
System.err.println("Failed to get input stream!");
return null;
}
}
public static PrintStream output(Socket socket){
try {
return new PrintStream(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
System.err.println("Failed to create output stream!");
return null;
}
}
public static Socket waitForConnections(ServerSocket server){
try {
return server.accept();
} catch (IOException e) {
e.printStackTrace();
System.err.println("Failed to accept connection!");
return null;
}
}
It works when i do it with a desktop project, but when i do it with an android project, it doesn't work.
ERROR:
Let me know if anyone has similiar problems or have found a solution.
Assuming both your PC and your Android device are connected to the same LAN (connected to the same router), you should try to use the server's internal IP address (usually looks like: 10.0.0.X or 192.168.X.X), which you can find by running the ipconfig command on the command line in a Windows PC, or ifconfig on Linux/MAC. If your PC and Android device are connected to different networks then you should use the server's external IP address like you did in your example. If it is the latter you should also forward the port your using (1234) to your PC in your router.
When the server is startet on your pc, you cannot connect from another device than your pc as long as you try to connect to localhost/127.0.0.1. Only when running the app on your pc as desktop application the connection will work since client and server are on the same host. For other clients you need to connect to the local LAN IP address of your PC. When you try to connect to localhost/127.0.0.1 from your phone it is looking for a server running on the phone and this is not the case.
Is the client network connection estabished in an UI thread/activity? If so, network connection should established in a separate thread, eg. AsynTask for short operations and services for longer streaming operations. http://developer.android.com/training/basics/network-ops/connecting.html#AsyncTask
I have created a small TCP server but it only connects to other computers on my LAN. I did forward the port but it is still not working.
connection method:
private boolean connect(){
try {
socket = new Socket(InetAddress.getByName(ip), port);
System.out.println("socket created");
dataOutput = new DataOutputStream(socket.getOutputStream());
dataInput = new DataInputStream(socket.getInputStream());
accepted = true;
} catch (IOException e) {
System.out.println("Unable to connect to the server");
return false;
}
System.out.println("Successfully connected to the server.");
return true;
}
listen method:
private void listenForServerRequest(){
Socket socket = null;
try{
socket = serverSocket.accept();
dataOutput = new DataOutputStream(socket.getOutputStream());
dataInput = new DataInputStream(socket.getInputStream());
accepted = true;
System.out.println("client joined");
}catch(IOException e){
e.printStackTrace();
}
}
opening the server:
private void initializeServer(){
try{
serverSocket = new ServerSocket(port,8,InetAddress.getByName(ip));
}
catch(Exception e){
e.printStackTrace();
}
}
It appears as if you're supplying an IP address to InetAddress.getByName(). It requires a host name. Specifically, it needs the host name corresponding to the network that the port is forwarded to. For example, if you're forwarding to your computer's (internal) ip address (say, 192.168.1.10), then it needs the host name that corresponds to that address (for example mycomputer.local). Java needs that host name to know what interface it should listen on. I'm surprised it worked at all.
If you do want to supply the IP address and not the host name, use InetAddress.getByAddress(byte[] addr) instead:
byte[] addr = new byte[4];
addr[0] = 192;
addr[1] = 168;
addr[2] = 1;
addr[3] = 10;
...
serverSocket = new ServerSocket(port,8,InetAddress.getByAddress(addr));
I want to check the online/offline status about a Database Server with Java.
Can I check this with a Socket connection over the port? I want to do this wihtout a Database connection with jdbc because the login and Database system info is unknown.
You can try the following:
try {
Socket socket = new Socket("127.0.0.1", port); //Port dependent on your DB/Server
// Server is up
socket.close();
}
catch (IOException e)
{
// Server is down
}
Yes, you can just open a Socket to the address and port of your databse server, if you get an IOException the server is down. (tested with postgress)
public boolean isDatabaseOnline(String address, int port) {
boolean result;
try {
Socket socket = new Socket(address, port);
socket.close();
result = true;
} catch (IOException e) {
result = false;
}
return result;
}
The above approaches don't really consider timing out in case the remote is unreachable, and a reasonable timeout should be defined because the default value is 20 seconds!!
You can state a timeout using the socket.connect method AFTER you create a blank socket.
SocketFactory sf = SocketFactory.getDefault();
try (Socket socket = sf.createSocket()) {
socket.connect(new InetSocketAddress(ipAdder, port), timeoutInMillis);
logger.info("database is up");
} catch (IOException e) {
logger.info("database is down");
}
The example above uses try with resources
I'm trying to create a simple multicast communication between my PC (Ubuntu, client) and my phone (Android, server).
Unicast/TCP connections work without any problem, the defined port (37659) opens both on PC and phone. When trying to use a MulticastSocket, no ports get opened. nmap tells me the specified port (36963) is a TCP port and that it is closed. (While the receive-method is being executed).
Am I doing something wrong? Or is the firewall blocking the multicast sockets? (I've tried about 20 different ports and none worked..., currently using port 36963)
EDIT: Also with the firewall completely down, nmap tells me the port is closed...
The server's code (phone):
private void multicastLoop() {
String res = Build.FINGERPRINT + "\n";
final InetAddress group;
final MulticastSocket socket;
final DatagramPacket response;
try {
group = InetAddress.getByName("224.0.0.115");
socket = new MulticastSocket(mport);
socket.setLoopbackMode(true);
socket.setSoTimeout(10000);
socket.joinGroup(group);
response = new DatagramPacket(res.getBytes(), res.length(), group, mport);
} catch (IOException e) {
e.printStackTrace();
return;
}
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while(isRunning) {
try {
byte[] data = new byte[1024];
DatagramPacket dm = new DatagramPacket(data, data.length);
socket.receive(dm);
Log.d("udp", "received");
if (Arrays.equals(dm.getData(), "someone there".getBytes())) {
socket.send(response);
}
} catch (SocketTimeoutException e) {
continue;
} catch (IOException e) {
e.printStackTrace();
}
}
try {
socket.leaveGroup(group);
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
t.start();
}
The client's code (computer):
public String[] findServers() {
String hello = "someone there";
try {
InetAddress group = InetAddress.getByName(mhost);
MulticastSocket socket = new MulticastSocket(mport);
socket.setLoopbackMode(true);
socket.setSoTimeout(60000);
socket.joinGroup(group);
DatagramPacket p = new DatagramPacket(hello.getBytes(), hello.length(), group, mport);
byte[] buffer = new byte[1024];
socket.send(p);
DatagramPacket r = new DatagramPacket(buffer, buffer.length);
socket.receive(r);
socket.leaveGroup(group);
socket.close();
String srinfo = "";
byte[] data = r.getData();
for (byte b: data)
srinfo += (char) b;
System.out.println("Server found at " + r.getAddress().getHostName() + ": " + srinfo);
} catch (SocketTimeoutException e) {
return new String[] {"timeout"};
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Make sure mhost is set to "224.0.0.115" not some machine name.
Make sure multicast is enabled on your router.
If the host is multi-homed, you need to join the multicast group via all local interfaces, not just the default one, which is what you're doing at present.
You could send the response back to the source address it came from, which is in the received datagram packet. That would also mean that the client doesn't need a MulticastSocket, only a DatagramSocket.