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()
Related
I have an assignment where I have to build a Client-Server communication using Java. So what I did was building a Client-Server connect using Sockets, the following way:
//Client code
Socket socket = new Socket("127.0.0.1", 4999);
//Server code
ServerSocket ss = new ServerSocket(4999);
Socket socket = ss.accept();
System.out.println("Client is connected");
For now, the communication between the client and the server is successful, I am able to send messages from client to server and vice versa. but the main problem is storing data on the server host, we were asked to store relevant data on the server host so the server could send it to the client.
Can someone please explain to me how to store data on the server and how to retrieve it ??
Thanks
To read from the server socket:
ServerSocket server = new ServerSocket(port);
Socket socket = server.accept();
DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
//Do whatever you want with the DataInputStream
Source: https://www.baeldung.com/java-inputstream-server-socket
Then we can move to the input stream processing, here is a sample:
...
int i;
char c;
...
try{
// reads till the end of the stream
while((i = in .read())!=-1) {
// converts integer to character
c = (char)i;
// prints character
System.out.print(c);
}
} catch(Exception e){
//Handle....
} finally {
// Close stream...
}
Source: https://www.tutorialspoint.com/java/io/inputstream_read.htm#:~:text=io.-,InputStream.,the%20returned%20value%20is%20%2D1.
For writing to the socket (the response to the client), just follow the following tutorial, no need to repeat it here:
http://www.avajava.com/tutorials/lessons/how-do-i-write-a-server-socket-that-can-handle-input-and-output.html
I hope it helps
I am trying to exchange some string data between a Python Server (ideally, a Raspberry Pi with some device connected through GPIO) and a Java Client (again, the main target would be an Android app). The following code, anyway, is running on a standard local PC.
This is the code for the server, taken (and slightly modified) from here:
import socketserver
import datetime
class MyTCPHandler(socketserver.StreamRequestHandler):
def handle(self):
now = datetime.datetime.now()
answer = now
self.data = self.rfile.readline().strip()
print("Read!")
if str(self.data) == 'date':
answer = now.date()
elif str(self.data) == 'time':
answer = now.time()
self.wfile.write((str(answer)+"\n").encode('utf-8'))
print("Sent!")
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
with socketserver.TCPServer((HOST, PORT), MyTCPHandler) as server:
print("Server is running on {}, port {}".format(HOST, PORT))
server.serve_forever()
The Java client is the following:
public class SocketTest {
public static void main(String[] args) {
try {
Socket s = new Socket("127.0.0.1", 9999);
PrintWriter out = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
out.println("date".getBytes());
String resp = in.readLine();
System.out.println("Received: " + resp);
} catch (IOException ex) {
Logger.getLogger(SocketTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
No exception is thrown whatsoever, it just gets stuck waiting for the response on the client side, and I can never see the "Read!" message on the server side.
The "date".getBytes() comes from somewhere on the net where I found that the Python sockets expect bytes (UTF-8), but in Java I'm sending strings directly, so it might be wrong.
Any help will be appreciated!
Turnes out, it was a flushing problem.
Apparently, the buffer is not flushed when the end of line is reached (which is how I was expecting it to behave).
Adding a simple out.flush() solved the problem.
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.
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 have a java server which is using TCP and sockets to connect to an Android application (the client) and sends strings (currently taken in from a scanner object) which are then displayed as notifications by the client.
heres the Server code without all the imports.
public class Server {
// define our Main method
public static void main(String[] args) throws IOException {
// set up our Server Socket, set to null for the moment.
ServerSocket serverSocket = null;
boolean isConnected = false;
// Lets try and instantiate our server and define a port number .
try {
serverSocket = new ServerSocket(6789);
isConnected = true;
System.out.println("*** I am the Server ***\n");
// make sure to always catch any exceptions that may occur.
} catch (IOException e) {
// always print error to "System.err"
System.err.println("Could not listen on port: 6789.");
System.exit(1);
}
// We always want to check for connection from Clients, so lets define
// a for ever loop.
for (;;) {
// define a local client socket
Socket clientSocket = null;
// lets see if there are any connections and if so, accept it.
try {
clientSocket = serverSocket.accept();
// don't forget to catch your exceptions
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
// Prepare the input & output streams via the client socket.
// fancy way of saying we want to be able to read and write data to
// the client socket that is connected.
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
PrintWriter outToClient = new PrintWriter(clientSocket.getOutputStream(),
true);
while (isConnected) {
// read a sentence from client
String hiFromClient = inFromClient.readLine();
// Set up the logging system and timestamp and log message.
Calendar currentDate = Calendar.getInstance();
SimpleDateFormat formatter=
new SimpleDateFormat("yyyy/MMM/dd HH:mm:ss");
String dateNow = formatter.format(currentDate.getTime());
try{
// Create file
File fstream = new File("log.txt");
FileWriter out = new FileWriter(fstream);
out.write(hiFromClient + " " + dateNow);
//Close the output stream
out.close();
} catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
// Print the client sentence to the screen
System.out.println("The Client said: "+hiFromClient);
// Reply to the client
Scanner scanner = new Scanner(System.in);
String sentence = scanner.nextLine();
outToClient.println(sentence );
System.out.println("The Server said: " + sentence);
}
// always remember to close all connections.
inFromClient.close(); // the reader
outToClient.close(); // the writer
clientSocket.close(); // and the client socket
}
}}
Growl uses port 23053 for notification forwarding. What i am hoping to do is to listen in on 23053 and send anything in from that as a string to the client connected at 6789. Sadly Growl binds the port number so a new Socket connection cant be made.
Any one have any ideas on how i could get notifications from the port number growl uses or even just use growl as the server for the client itself (the client's code is very similar to the servers by the way just using Socket instead of ServerSocket)
Any help on this would be greatly appreciated, its wrecking my brain
All the best,
Patrick.
There is a round-about way you could do it. If you are desperate, read on:
Growl can forward any notifications it receives to another machine running Growl (configured on the Network tab). Growl uses the GNTP protocol (a TCP-based protocol: http://www.growlforwindows.com/gfw/help/gntp.aspx) to forward the messages. The trick is that that 'other machine running Growl' doesnt have to really be another machine OR running Growl per se, it just needs to appear to Growl that it is. Growl (on the Mac, which is what I assume you are using) will automatically detect any other machines on the network running Growl (using Bonjour and looking for the _gntp._tcp service name), so if your server advertises itself as supporting the GNTP protocol, Growl should show it in the list of available destinations. (Growl for Windows also lets you manually add a hostname/port to forward to, but I dont believe the Mac version currently allows that).
So then you could configure Growl to forward notifications to your server using its already-built-in capabilities. You would have to implement code in your server to receive the GNTP packets (the format is very similar to HTTP headers) and parse them. Then you could forward the notifications using your current server code.
Still with me? I did say it was round-about, but it is not only technically possible, but I have built a Growl-impersonating daemon before so that I could have notifications forwarded from Growl to my custom code. Not suggesting it as the best idea, but just an alternative since you asked.