I've been working on a simple Android TCP Server, so I can connect from a TCP Client and pass data back and forth.
I am encountering an weird problem, my android phone creates the TCP Socket, and I am able to connect to it via Hercules utility (A TCP client). The connection goes through, however the program is still blocking at the ServerSocket.accept() method.
Could anyone shed some light on this issue? Here is my java function.
public void TcpServer()
{
try
{
Socket s = null;
ServerSocket ss = null;
System.out.println("TCP Server Starting");
ss = new ServerSocket(27015);
s = ss.accept();
System.out.println("New connection! Yay");
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
String incomingMsg = input.readLine();
System.out.println("Received: " + incomingMsg);
}
catch (Exception e)
{
}
}
Related
I am creating and testing a simple TCP server on an Android emulator.
I use a simple Java client program to try to connect to the server running on the emulator. I attempt to send a simple string like "hello world".
I think the connection between the client and server is successfully initialized; however, data is not routed to the Android device.
The server thread blocks at line clientSentence = inFromClient.readLine(); and the client thread blocks at String serverResponse = inFromServer.readLine();.
I have port forwarded local host port 6100 to AVD virtual port 7100 as per Google docs with ADB
adb -s emulator-5554 forward tcp:6100 tcp:7100
Here is Java class TCPTestClient
public class TCPTestClient
{
public static void main(String argv[]) throws Exception
{
String sentenceToServer = "hello server";
System.out.println("initializing socket");
Socket clientSocket = new Socket("127.0.0.1", 6100);
System.out.println("socket initialized");
System.out.println("getting output stream to server");
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
System.out.println("found output stream to server");
System.out.println("getting input stream from server");
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
System.out.println("found input stream from server");
System.out.println("writing sentence to server");
outToServer.writeBytes(sentenceToServer );
System.out.println("sentence written");
System.out.println("waiting for sentence response from server");
String serverResponse = inFromServer.readLine();
System.out.println("serverResponse = "+serverResponse);
System.out.println("socket closed");
clientSocket.close();
}
}
Here is Android app method initTcpTestServer()
private void initTcpTestServer()
{
Log.d("TAG", "initTcpTestServer()");
try
{
String clientSentence;
ServerSocket welcomeSocket = new ServerSocket(7100);
while ( true )
{
Log.d("TAG", "looking for socket");
Socket connectionSocket = welcomeSocket.accept();
Log.d("TAG", "socket accepted");
Log.d("TAG", "getting input stream");
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));
Log.d("TAG", "input stream found");
Log.d("TAG", "getting output stream");
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
Log.d("TAG", "output stream found");
Log.d("TAG", "reading input stream");
clientSentence = inFromClient.readLine();
Log.d("TAG", "input stream read");
Log.d("TAG", "input = " + clientSentence);
Log.d("TAG", "writing output back to client");
outToClient.writeBytes(clientSentence);
Log.d("TAG", "output written back to client");
}
}
catch ( IOException e )
{
e.printStackTrace();
}
}
If I initialize the TCP server first I get output
initTcpTestServer()
looking for socket
After initializing the TCP server and then initializing the TCP client I get from the server
getting input stream
input stream found
getting output stream
output stream found
reading input stream
and from the client
initializing socket
socket initialized
getting output stream to server
found output stream to server
getting input stream from server
found input stream from server
writing sentence to server
sentence written
waiting for sentence response from server
so it appears that the socket is established, but the server blocks at line
clientSentence = inFromClient.readLine();
and the client blocks at
String serverResponse = inFromServer.readLine();
becuase the client has written the data, but the server has never received it, and the client is hanging waiting for the server's reponse.
Thank you Scary Wombat. Adding a "\n" at the end of the String resulted in a successful TCP message to the server. A TCP server can indeed be set up on an Android emulator by configuring port forwarding on the AVD virtual router with ADB. However, I have only testing this on local host.
I am trying to create a client-server system: my server is a raspberry pi which is running a python webserver on it, and my client is on a different pc and is written is Java. The idea is that the server collects data and when it gets a request from a client, it sends the data to the client.
My client should request the data, wait for 10 seconds and request again etc.
Currently this system is working, but after a day or so, the client starts getting a lot (but not continuously) socket timeouts. I think that this may be the case because for each request I create a new socket for communication and I think that after a day the sockets run out or something like that. This is the code the client executes every 10 seconds:
public static String getData() throws Exception {
TreeSet<Integer> primes = MathUtils.primesSieve(10000);
try {
String data = "";
Socket socket = new Socket(SERVER_ADDRESS, SERVER_PORT);
socket.setReuseAddress(true);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
int msg = ColUtils.drawRandomlyWithReplacement(primes, 1, ArrayList::new).get(0);
out.write(msg+"");
out.flush();
String input;
while ((input = in.readLine()) != null) {
data += input;
if (!data.endsWith("#" + prod(msg))) {
throw new Exception("WRONG ECHO");
}
}
socket.close();
return data;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
I tried fixing it by having a socket which is a member of the encapsulating class, but after a singe request the inputstream stopped working. Is there any way where I can keep using a single socket for ALL communications with the server? Or is this the recommended way of doing this sort of communication?
Try first closing the socket and input, output streams. As in your code there is no quarantee that you are releasing the acquired objects.
PrintWriter out = null;
BufferedReader in = null;
Socket socket = null;
try {
...//your statements
} catch (Exception ex) {
//catch or whatever
} finally {
if (out != null) out.close();
if (in != null) in.close();
if (socket != null) socket.close();
}
try to make the Socket object static If possible that would created only once and read the data every 10 sec
Otherwise u can instantiate it before calling the getData method and then read it.
Doing so will make only 1 copy of Socket.
And I don't think u are running out of ports.
The reason might be quit simple that your Program is not receiving the data before the time out. and it is a normal case in a bad network
Socket generally waits indefinitely until it receives data if the timeout is not set Programmatically
I am trying to connect from a android emulator to a application on my desktop and send a line of text.
My app is able to connect to the server, but when ever i try to read data its always null
Server application running on my desktop:
ServerSocket ss = new ServerSocket(9001);
Socket cs = ss.accept();
if (cs.isConnected()) {
System.out.println("Client connected.");
}
BufferedReader reader = new BufferedReader(new InputStreamReader(cs.getInputStream()));
String str = reader.readLine();
System.out.println("Data:" + str);
Client application running in android app emulator:
InetAddress addr = InetAddress.getByName("10.0.2.2");
Socket socket = new Socket(addr, 9001);
if (socket.isConnected()) {
Log.d("APP", "socket connected");
}
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
String str = "this is a sample";
pw.write(str);
I can see that the isConnected function of the socket on both the client and server turns true.
But the Data printed on the server is always null.
Thanks
Try adding a flush call after the 'pw.write(str)' statement:
pw.flush();
I am building a small chat application in which client A wants to send something to client C with server B in between. First of all is this a correct approach for the problem??. I am able to send and receive data to and from a server but it is limited to only the client.For example if Client A sends data to server B and client C is sending data to server B then i can send data back to A and C just like an echo server. But what i want is to forward data coming from Client A to Client C via server B.
The following is the server code:
public class Server {
public static void main(String[] args) {
int port = 666; //random port number
try {
ServerSocket ss = new ServerSocket(port);
System.out.println("Waiting for a client....");
System.out.println("Got a client :) ... Finally, someone saw me through all the cover!");
System.out.println();
while(true) {
Socket socket = ss.accept();
SSocket sSocket = new SSocket(socket);
Thread t = new Thread(sSocket);
t.start();
System.out.println("Socket Stack Size-----"+socketMap.size());
}
}
catch (Exception e) { }
}
}
class SSocket implements Runnable {
private Socket socket;
public SSocket(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
DataInputStream dIn = new DataInputStream(in);
DataOutputStream dOut = new DataOutputStream(out);
String line = null;
while (true) {
line = dIn.readUTF();
System.out.println("Recievd the line----" + line);
dOut.writeUTF(line + " Comming back from the server");
dOut.flush();
System.out.println("waiting for the next line....");
}
}
catch (Exception e) { }
}
}
The client code is :
public class Client {
public static void main(String[] args) {
int serverPort = 666;
try {
InetAddress inetAdd = InetAddress.getByName("127.0.0.1");
Socket socket = new Socket(inetAdd, serverPort);
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
DataInputStream dIn = new DataInputStream(in);
DataOutputStream dOut = new DataOutputStream(out);
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Type in something and press enter. Will send it to the server and tell ya what it thinks.");
System.out.println();
String line = null;
while (true) {
line = keyboard.readLine();
System.out.println("Wrinting Something on the server");
dOut.writeUTF(line);
dOut.flush();
line = dIn.readUTF();
System.out.println("Line Sent back by the server---" + line);
}
}
catch (Exception e) { }
}
}
When your clients connect to the server, your server creates a Socket for it, here it is Socket socket = ss.accept();, your socket variable will be holding that client.
now if you just keep adding your client socket to a arraylist in your while loop, you will have a list of clients actively connected with your server like:
after the accept:
clients = new ArrayList<DataOutputStream>();
Socket socket = ss.accept();
os = new DataOutputStream(socket.getOutputStream());
clients.add(os);
Now as you have all the clients in that clients arraylist, you can loop through it, or with some protocol define which client should i send the data after reading.
Iterator<DataOutputStream> it = clients.iterator();
while ((message = reader.readLine()) != null) { //reading
while (it.hasNext()) {
try {
DataOutputStream oss = it.next();
oss.write(message);//writing
oss.flush();
}
catch (Exception e) { }
}
}
This will loop through all the available clients in the arraylist and will send to all. you can define ways to send to only some.
For example:
maintain a ActiveClients arraylist and with some GUI interaction may be or maybe, define what all clients you want to send the message.
Then add just those clients outputStreams to ActiveClients
ActiveClients.add(clients.get(2));
or remove them, if you don't want them.
ActiveClients.remove(clients.get(2));
and now just loop through this arraylist to send the data as above.
You can create message queue for each client:
Client A sends message 'Hi' with address Client C to server B.
Server B receives message and adds it to message queue of client C.
Thread in server B which communicates with client C check message queue, retrieve message and sends it to client C.
Client C receives message.
If I am not mistaken, you must be having a problem with receiving a message from the Server or SSocket class. What happens with your code is that when you send a message from the client to the server the Server class receives your messages also gives an echo of the message in the client. However, when you send a message from the Server class, you don't get any messages in the Client Class.
To get this to work, you would have to modify your code in the following fashion:
SSocket Class
String line = null;
while (true) {
line = dIn.readUTF();
System.out.println("Recievd the line----" + line);
dOut.writeUTF(line + " Comming back from the server");
dOut.flush();
System.out.println("waiting for the next line....");
}
You should add these lines:
String Line2 = take.nextLine(); //The user types a message for the client
dOut.writeUTF(Line2 + " Comming back from the server"); //The message is sent to the client
Replace the while loop with this one and it will work fine.
while (true) {
line = dIn.readUTF(); //Takes the msg from the client
System.out.println("Recievd the line----" + line); //Prints the taken message
String Line2 = take.nextLine(); //The user types a message for the client
dOut.writeUTF(Line2 + " Comming back from the server"); //The message is sent to the client
dOut.flush();
System.out.println("waiting for the next line....");
}
i'm trying to find out how to create a TCP server with SSL in java. But i don't get what i really need. Do i have to import key-files into java, and i so, how to do this? Or do i just need to change the type of the socket from Socket to SSLSocket? I've read some articles but couldn't find anything helpful because all of them just take http for communicating. I would need it for my own protocol. In my case it would be to have a program like this:
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();
}
to use a SSL connection. So how to do this?
Thanks,
Thomas
I found this with a quick Google search.
Here.