I'm developing an Android client app which talks to server via a plain TCP Socket, let's assume that the server ip 192.168.1.2 and the androdi device ip is 192.168.1.3.
I open the socket, i check if socket is connected (i get true as result) and after that i write a presentation message.
Here is my code
// scoket setup
Sockets = new Socket(addressToConnect, 2015);
s.setSoTimeout(2500);
setTcpNoDelay(true);
// if i'm connected
if (s.isConnected()) {
// wrapping streams
DataInputStream dis = new DataInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
// sending data
String presentationMessage = "Presentation message content--- TERM";
dos.write(presentationMessage.getBytes("UTF-8");
dos.flush();
// buffers
byte[] readBuffer = new byte[4096];
StringBuffer responseBuffer = new StringBuffer();
// read data until command terminator string is found
boolean readResponse = true;
while (readResponse) {
int dataBufferLength = dis.read(readBuffer);
String chunk = new String(readBuffer, 0, dataBufferLength, "UTF-8"));
responseBuffer.append(chunk);
readResponse = ! chunk.endWith("--- TERM");
}
// Process data here
} else {
// Notify missing connection here
}
// here i close the socket
When i execute this code the execution seems working like a charme until the first read which timesout.
Sniffing the used WIFI network with a third machine i can't see the connection establishment and the written stream even if the code doesn't throw any exception before the read timeout.
I granted the android.permission.INTERNET in manifest.
Are there some other permissions to grant? or what i'm doing wrong?
Executing the same code in a standard Java SE environment everything goes fine.
I'm testing the code on a Nexus 5, Nexus 9 and Samsung S3 and S4 and the project is compatible with API 14+
Edit: Fixed typo in code example
You are reading from dos and writing to dis. You should reverse that.
Related
I am creating a program where an android device requests a file from a Web Server(running python).The server can receive over sockets with no problem the path of the requested file but i dont know how i can make my android device to wait for a responce.
Here is the android code(as a client requesting a file from web server):
try {
Socket socket = null;
socket = new Socket("192.168.1.9", 4000);
DataInputStream input = new DataInputStream(socket.getInputStream());
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
String str = getURL();
output.writeBytes(str);
output.close();
input.close();
socket.close();
{
}
} catch (IOException e) {
}
Log.d("communicationService", "URL transferred with success");
And the python script running on Web Server(It can receive thefile path but i have problem sending the file)
import socket
import sys
HOST, PORT = '192.168.1.9', 4000
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serverSocket.bind((HOST,PORT))
serverSocket.listen(10)
print 'Server is on and listening to %s ... ' % PORT
while True:
clientSocket, clientAddress = serverSocket.accept()
print 'A client was connected.....'
incomingURL = clientSocket.recv(1024)
print incomingURL
clientSocket.close()
Any advice and tip would be really helpful...
I imagine you should be able to get away with SimpleHTTPServer
If you need to get fancier with a full blown webservice, WSGI is very popular.
On the client side Requests library is by far the easiest way that I've found to make http requests in python. (just had to plug that one because it's that good)
Well i managed to transfer the files in the end(For those that are interested in apps of this kind).What i did was to create another socket and sent a stream back to client.
file = open("path_of_file", "rb")
s = socket.socket()
s = connect((addr,port))
l = file.read(1024)
while (l):
s.send(l)
l.f.read(1024)
file.close()
s.close()
TelnetClient telnet = new TelnetClient();
telnet.connect( "192.168.0.6", 23 );
PrintWriter out =
new PrintWriter(telnet.getOutputStream(), true);
DataInputStream in =
new DataInputStream(telnet.getInputStream());
BufferedReader stdIn =
new BufferedReader(
new InputStreamReader(System.in));
String userInput;
byte buffer[] = new byte[1024];
int bytesRead;
while ((bytesRead=in.read(buffer,0,1024)) != -1) { // read from server
System.out.print(new String(buffer, 0, bytesRead, "UTF-8"));
userInput = stdIn.readLine();
if (userInput != null) {
out.println(userInput);
out.flush();
}
}
telnet.disconnect();
Hello I have a problem with this program during the connection to the server.
This program should allow me to start a telnet connection to a server and send to it some commands and return me the result of these but when I start the connection some times it return me only the HELLO of the server (Welcome to Microsoft Telnet Service) and not the entire message including LOGIN:
When I send commands the response of these is delayed.
For example i write "DIR" and the response is written only when I press enter two times...
Where I wrong? Please help me.
When trying to connect to network services using such protocol (Telnet, FTP ,SSH ..) which are session based protocol and require to keep your connection alive and be interactive with the service , it's recommended to use available Java API instead of reinventing the wheel (only if you are asked to do without a third party library), in your case you can use Apache Common Net wich provide a set of helpful features to connect to servers using many network protocols including Telnet .
I am writing a proxy server in Java.
Initially, I do (simplified)
server = new ServerSocket(5568);
incoming = server.accept();
input = incoming.getInputStream();
...
outgoing = new Socket(host, 80);
output = outgoing.getOutputStream();
output.write(inputbuffer, 0, i);
where inputbuffer is some collection of bytes received so far (I read the incoming data up until the part where I know the host header, and then open a connection to the server and send what I have so far). So server is my welcome socket, input is the data coming to my proxy from the client, and output is the data to the serve from my proxy.
Next, I want the output from the server to be written to the client in parallel with the client still possibly writing stuff to the server. So I create a separate thread to read from the client:
final InputStream finalInput = input;
final OutputStream finalOutput = output;
Thread sendingStuff = new Thread(){
public void run(){
int c;
while ((c = finalInput.read()) != -1){
finalOutput.write((byte)c);
finalOutput.flush();
}
finalInput.close();
finalOutput.close();
}
}
sendingStuff.start();
Finally, I have a different section in the main thread to read from the server and write that to the client.
InputStream reverseInput = outgoing.getInputStream();
OutputStream reverseOutput = incoming.getOutputStream();
int c;
while ((c = reverseInput.read()) != -1){
reverseOutput.write((byte)c);
reverseOutput.flush();
}
reverseInput.close();
reverseOutput.close();
What happens is I get input, and send output, but the browser spins forever and the line in the thread that's reading from the client never gets a -1 signal.
A lot of the time I get errors that say things like "invalid header name" or "your browser sent a request that the server could not understand" and I think it has to do with this problem I'm having. One time I even got an IOException: Socket Closed on the line that reads from the client.
So why isn't the client sending an EOF? And is this the right way to go about doing this?
"I think it's because my HTTP request has Connection: keep-alive. How do I handle this?"
I think maybe you can just open your socket once for one connection.
Try to have flag like isNewConnection. set it to true at first and after the connection is initiated, set it to false.
I did a Java Socket server, and a C++ Client.
However, the client connects to the server, without problems.
But when I write something client-server, the server doesn't catch the message.
What I'm doing wrong?
A little bit of the code of the Java Server:
DataInputStream dis=new DataInputStream(usrSocket.getInputStream());
ByteArrayOutputStream out = new ByteArrayOutputStream();
int data;
while((data = dis.read())>=0) {
out.write(data);
}
byte[] bytes = out.toByteArray();
String decrypt = new String(bytes);
if(decrypt.equals("status")){
System.out.println("Status emitted.");
}
System.out.println("Received a message.");
C++ Client writing:
QByteArray qba;
qba.append(text);
sock->write(qba.data());
qDebug() << "Send status";
I need help with that, thank you very much.
(that variable "text" it's a QString)
EDIT
Java server: That's only one part of all the code, the main thread waits for connections (Socket sock = server.accept()) and create a new thread for each user.
The code that I published of the java server, its one part of that threads for the users.
If you need ALL the code, plese tell me.
I will be waiting the answers!
Thank u very much!
Sorry if I answer ya late.
Try this code for Java Server.
ServerSocket ss = new ServerSocket(Port_No);
Socket incomingClient = ss.accept();
InputStream i = incomingClient.getInputStream();
OutputStream o = incomingClient.getOutputStream(); // Use it write to the Client Socket
InputStreamReader isr = new InputStreamReader(i);
BufferedReader br = new BufferedReader(isr);
String str = new String();
while ((str = br.readLine())!=null){
// do what you want with the data received in str.
}
As youre using QTcpSocket, it highly likely that you are running the client in the default asynchronous mode. This means after when you write after calling connectToHost, nothing will be sent as the socket is not connected.
Try using:
socket->connectToHost(hostAddress, hostPort, QIODevice::ReadWrite);
if (socket->waitForConnected()) {
QString text = "test string";
QByteArray array;
array.append(string);
qDebug() << socket->write(array);
} else {
// connect error!
}
Your Java code reads the socket until EOS and then prints something, which by the way is not a decryption operation. Your C++ client writes something and never closes the socket. So the server can never get out of the read loop.
If I read it correctly it is caused by the fact that your client is still running. Read() returns number >= 0 until the client socket is closed.
This question already has answers here:
Java Socket why server can not reply client
(4 answers)
Closed 3 years ago.
So I have a TCP client running on an Androidt tablet, and I have a c++ server running on a PC.
I send data from my tablet to the PC and the PC can read them just fine, but when the PC tries to send back a message to the tablet, the tablet just receives nothing. It gets stuck in the readLine() call trying to read something.
So here is the java methods sending and then waiting for a response
#Override
protected Void doInBackground(Void... arg0)
{
String msg = "";
Socket socket = null;
DataOutputStream outToServer = null;
BufferedReader msgFromServer = null;
try
{
// Socket used for I/O with the server
socket = new Socket("192.168.20.100", 48501);
// Writing to the server
outToServer = new DataOutputStream( socket.getOutputStream() );
// Reading from the server
msgFromServer = new BufferedReader( new InputStreamReader( socket.getInputStream() ) );
DataInputStream iStrReader = new DataInputStream( socket.getInputStream() );
// Initial comm
outToServer.writeBytes( "MainCamConnect" );
msg = msgFromServer.readLine(); // Get stuck here
Log.d( "NETWORK", msg );
socket.close();
}
catch( UnknownHostException e )
{
e.printStackTrace();
}
catch( IOException e )
{
e.printStackTrace();
}
return( null );
}
and the message I send from the PC is this : "StartDelayTest\n"
I know the server can send message just fine because I tested it with a simple c++ TCP client and it worked just fine, but when I run it on the tablet, the tablet can't get anything
EDIT:
OS : Windows 7 64 bits Professional edition
EDIT 2:
I've run wireshark on my computer and I can confirm that the packets are being sent to the right address IP, so the problem is indeed in the receiving end (the android app)
You are reading lines but you aren't writing them. writeBytes() just writes those bytes. Lines end with a newline. readLine() will block until it receives one.
I would try using public int read(char[] cbuf, int off, int len) instead so your code would be something like:
char[] buffer = new char[256];
int count = read(buffer, 0, 256);
readline for network buffers isn't used very often in typical client server apps.