Android socket connection between hotspot and client - java

I am making an app that checks for certain connections (looking for a list of SSIDs) and creates an hotspot for said connection if it doesn't find any. Basically it should act as a local area network.
I am successful in creating the hotspot, and after that it listens on a server socket for incoming connections:
Thread socketThread = new Thread(new Runnable() {
#Override
public void run() {
int port = Constants.PORT + socketList.size()-1;
try {
ServerSocket serverSocket = null;
serverSocket = new ServerSocket(port);
Log.d(TAG, "Socket listening for connections: " + port);
Socket client = serverSocket.accept();
Log.d(TAG, "Server: connection done");
InputStream inputstream = client.getInputStream();
DataInputStream commStream = new DataInputStream(inputstream);
byte[] b = new byte[16];
while (commStream.read(b,0, 16) != -1)
Log.d(TAG, new String(b, "ASCII"));
serverSocket.close();
Log.d(TAG, "Server socket done");
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}
});
socketList.add(socketThread);
socketThread.start();
If I create the hotspot and connect to it with my pc I am able to use netcat and connect with said socket:
netcat 192.168.43.1 8988
Where 192.168.43.1 is the default Android IP address for the hotspot and 8988 is the port I'm using.
However, when I try to do the same through another device running the app and connecting to the hotspot, it doesn't work.
Here's the client code:
clientThread = new Thread(new Runnable() {
#Override
public void run() {
int port = Constants.PORT ;
try {
Socket socket =new Socket();
socket.bind(null);
socket.connect((new InetSocketAddress("192.168.43.1", port)), 20000);
OutputStream stream = socket.getOutputStream();
DataOutputStream commStream = new DataOutputStream(stream);
commStream.write("1234567890123456".getBytes());
socket.close();
Log.d(TAG, "Client socket done");
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}
});
clientThread.start();
It doesn't even connect to the server socket, it just waits until timeout. Is there anything I'm doing wrong here?
Thanks in advance.

You cannot create a server socket with IP(192.168.43.1) on the device which has created the hotspot. So just reverse the server socket on another device that has been connected to the hotspot.
e.g. Let's say you have created hotspot on Device A and Device B has been connected to A so create the server socket on Device B with assigned local IP and create Socket instance in A by finding the IP of Device B.

Related

Global Server Socket

I created a socket server that I wanted to assign an address to so that the socket server is global and available to clients. However, I tried for a long time to associate the server with the address and failed, since it is always a local address when I specify it.
(IP is a string, which is outside of this code snippet)
Here is my code:
new Thread(new Runnable() {
#Override
public void run() {
try {
InetAddress address = InetAddress.getByName(IP);
ServerSocket server = new ServerSocket(8080,0,address);
while(true) {
Socket client = server.accept();
System.out.println("Client connected!");
}
} catch(IOException err) {
err.printStackTrace();
}
}
}).start();
So is it possible to host the socket server globally or is the SocketServer only for localhosting?

Server is not connecting

I have a void method called startServerConnection() that connects the server to a port, in this case 7777. This method is called inside an action listener for a button in another class, ClientGUI.
I'm pretty sure the code is correct, but for some reason the only output I get is "Waiting for connection..."
public void startServerConnection(){
try{
serverSocket = new ServerSocket(portNumber);
while(true){
System.out.println("Waiting for a connection...");
Socket clientSocket = serverSocket.accept();
System.out.println("Connection established on port: "+clientSocket.getLocalPort());
ClientConnection clientConnection = new ClientConnection(clientSocket);
Thread thread = new Thread(clientConnection);
thread.start();
}
}
catch(Exception e){
e.printStackTrace();
return;
}
}
EDIT
Client class, connectClient method:
public void connectClient(String user){
try{
host = clientSocket.getInetAddress();
clientSocket = new Socket(host,port);
new ClientHandler(clientSocket).run();
String accepted = "Connection for host "+host+" accepted on port: "+clientSocket.getPort();
}
catch(Exception e){
//sendMessage("Connection error: "+e);
//serverGUI.appendEventsLog("Client "+new ClientGUI(username, port)+" failed to connect");
}
}
Any ideas on what's wrong?
Update:
public void connectClient(String user){
try{
clientSocket = new Socket(host,port);
// Use PrintWriter to send data out to server
// Use BufferedReader to receive data from server
}
catch(Exception e){
//sendMessage("Connection error: "+e);
//serverGUI.appendEventsLog("Client "+new ClientGUI(username, port)+" failed to connect");
}
}
host is the IP address or the hostname, if server/client are running on the same machine, you can either use "127.0.0.1" or "localhost"; port is a value of int, in your case is 7777
Original:
accept() is a blocking function. the code afterwards would not go thorough until a connection is established.
You have to build a client side and request for connection, once the server and client is connected, you will see "Connection established on port.."
public Socket accept() throws IOException
Listens for a connection to be made to this socket and accepts it. The method blocks until a connection is made.

Java - Which IP to use for the ServerSocket and Socket classes?

I just recently found the ServerSocket and Socket class found in the Java library and so I wanted to make a simple messaging app. The purpose of the app is to be able to communicate with someone on a different network than mine (I am the server side and have my own client side).
Here is the Messenger_Server.java's connecting method
public static void main (String [] args)throws IOException{
InetAddress ip;
try{
final int PORT = 444;
ip = InetAddress.getLocalHost();
ServerSocket server = new ServerSocket(PORT);
System.out.println("Waiting for clients...");
System.out.println(server.getInetAddress() + " " + ip.getHostAddress());
while(true){
Socket sock = server.accept();
connectionArray.add(sock);
System.out.println("Client connected from " + sock.getLocalAddress().getHostName());
addUserName(sock);
Messenger_Server_Return chat = new Messenger_Server_Return(sock);
Thread X = new Thread(chat);
X.start();
}
} catch(Exception e) {
e.printStackTrace();
}
}
Here is the client's connecting method from Messenger_Client.java
public static void connect(){
try{
final int PORT = 444;
// the ip below is the one i get as my ipv4
Socket sock = new Socket ("10.122.***.***",PORT);
System.out.println("you be connected to: " + InetAddress.getByAddress(InetAddress.getLocalHost().getAddress()));
chatClient = new Messenger_Client(sock);
PrintWriter out = new PrintWriter(sock.getOutputStream());
out.println(userName);
out.flush();
Thread X = new Thread(chatClient);
X.start();
}catch (Exception X){
X.printStackTrace();
JOptionPane.showMessageDialog(null, "Server not responding.");
System.exit(0);
}
}
So I gave the client side of the program to my friend and he said the host could not be found. Which IP should I use so my friend can connect to my ServerSocket, and could there be anything limiting my friend from connecting to me?

Java proxy not showing anything: client <--> server

This is my code:
import java.io.*;
import java.net.*;
public class proxy {
public static void main(String[] args) throws IOException {
try {
String host = "gamea.clashofclans.com";
int remoteport = 9339;
ServerSocket ss = new ServerSocket(0);
int localport = ss.getLocalPort();
ss.setReuseAddress(true);
// Print a start-up message
System.out.println("Starting proxy for " + host + ":" + remoteport
+ " on port " + localport);
// And start running the server
runServer(host, remoteport, localport,ss); // never returns
System.out.println("Started proxy!");
} catch (Exception e) {
System.err.println(e);
}
}
/**
* runs a single-threaded proxy server on
* the specified local port. It never returns.
*/
public static void runServer(String host, int remoteport, int localport, ServerSocket ss)
throws IOException {
// Create a ServerSocket to listen for connections with
System.out.println("Connected to Client!");
final byte[] request = new byte[2048];
byte[] reply = new byte[4096];
while (true) {
Socket client = null, server = null;
try {
// Wait for a connection on the local port
client = ss.accept();
System.out.println("Client Accepted!");
final InputStream streamFromClient = client.getInputStream();
final OutputStream streamToClient = client.getOutputStream();
// Make a connection to the real server.
// If we cannot connect to the server, send an error to the
// client, disconnect, and continue waiting for connections.
try {
server = new Socket(host, remoteport);
System.out.println("Client connected to server.");
} catch (IOException e) {
PrintWriter out = new PrintWriter(streamToClient);
out.print("Proxy server cannot connect to " + host + ":"
+ remoteport + ":\n" + e + "\n");
out.flush();
client.close();
System.out.println("Client disconnected");
continue;
}
// Get server streams.
final InputStream streamFromServer = server.getInputStream();
final OutputStream streamToServer = server.getOutputStream();
// a thread to read the client's requests and pass them
// to the server. A separate thread for asynchronous.
Thread t = new Thread() {
public void run() {
int bytesRead;
try {
while ((bytesRead = streamFromClient.read(request)) != -1) {
streamToServer.write(request, 0, bytesRead);
streamToServer.flush();
}
} catch (IOException e) {
}
// the client closed the connection to us, so close our
// connection to the server.
try {
streamToServer.close();
} catch (IOException e) {
}
}
};
// Start the client-to-server request thread running
t.start();
// Read the server's responses
// and pass them back to the client.
int bytesRead;
try {
while ((bytesRead = streamFromServer.read(reply)) != -1) {
streamToClient.write(reply, 0, bytesRead);
streamToClient.flush();
}
} catch (IOException e) {
}
// The server closed its connection to us, so we close our
// connection to our client.
streamToClient.close();
} catch (IOException e) {
System.err.println(e);
} finally {
try {
if (server != null)
server.close();
if (client != null)
client.close();
} catch (IOException e) {
}
}
}
}
}
When I run it I get to the message "Connected to client" (line 40) but after that nothing is happening in the window. I don't get the "Client has connected to the server message" so I assume the problem is somewhere around there?
Why is this happening? Does anyone know a fix?
I'm very new to java so please don't be harsh on me.
Your "Connected to Client!" message is misleading. At that point, you are starting your server and clients will soon be able to connect, but no clients have connected yet. Your program is waiting for
client = ss.accept();
to return. ServerSocket.accept waits for a connection to be made across the port. You need another thread, program, or computer to connect to this port to begin hosting them as a client. Make sure that this other thread, program, or computer is properly configured to connect to your open port. You likely need to either set ServerSocket to use a fixed port, or to determine what port it has opened a socket on and tell your other program what port to use.

Can a process connect to a socket that itself created?

EDIT: The code below throws no exception but has no output and hangs. It should output "Test message". In main(), we start a thread that's given a server socket listening on a random port. The main thread the tries to connect and communicate with the ServerSocket on that same random port, but is apparently failing. Why?
public class IntraProcSockTest {
private static int port;
private class Listener extends Thread {
public Listener() {
}
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(0);
port = serverSocket.getLocalPort();
Socket socket = serverSocket.accept();
BufferedReader in;
String fromClient;
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
while ((fromClient = in.readLine()) != null) {
System.out.println("From client: " + fromClient);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public IntraProcSockTest() {
new Listener().start();
}
public static void main(String[] args) {
new IntraProcSockTest();
try {
Thread.sleep(5000);
Socket socket = new Socket("localhost", port);
PrintWriter socketOut = new PrintWriter(socket.getOutputStream());
socketOut.println("Test message");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
A process can connect to a socket created by itself, there is no problem. Show us the code that throws an exception and/or more details about the exception.
First of all, be careful not to specify a local port for the client socket (the one connecting to the other which is listening). Let the OS choose a random port. Remember that any socket is identified by four elements (remote host, local host, remote port, local port), if you bind both the server socket and the client socket on the same local port, let it be 4498, both sockets are defined as follows: (localhost, localhost, 4498, 4498) and this doesn't work. I suspect this might be your problem.
To avoid such problems, client sockets are often bound to a random port, chosen by the OS. Show us your code, expecially the part in which the client sockets gets created and connects to the server socket.
And about IPC, it is not always bad to use sockets as an inter-process or even intra-process communication technique. The performance is worse, obviously, and you might loose some code readability, but your software will be easily portable to a network (distributed) application. It's up to your plans, it's not like IPC sockets == bad.
To create a Socket connection in one thread you can.
ServerSocket ss = new ServerSocket(0); // open a random free port.
Socket c = new Socket(ss.getInetAddress(), ss.getLocalPort());
Socket s = ss.accept();
ss.close();
final byte[] bytes = "Hello World!".getBytes();
final OutputStream out = c.getOutputStream();
out.write(bytes.length);
out.write(bytes);
final DataInputStream in = new DataInputStream(s.getInputStream());
int len = in.read();
final byte[] b = new byte[len];
in.readFully(b);
System.out.println(new String(b));
c.close();
s.close();
If all you want is IPC within a Process, a socket is not the fastest or simplest way to go. Try using a Pipe (NIO) or PipeInput/OutputStream (IO). Its faster and simpler.
Pipe pipe = Pipe.open();
SinkChannel sink = pipe.sink();
SourceChannel source = pipe.source();
or
PipedOutputStream output = new PipedOutputStream();
PipedInputStream input = new PipedOutputStream(output);
BTW: You can connect a client and server Socket in the same thread, however
Using an Exchanger is 10x faster, and using a ring buffer is faster again.
If you want convenience, using an ExecutorService is the best way to deleagte work to a background pool of threads. This can still perform millions of tasks per second.

Categories

Resources