I am new to programming and has been looking through tutorials for my project. Please forgive me if I may seem clueless about most things.
I am currently working on a project that requires an Android client to send string data to a Python server where the data will be processed and sent back from the Python Server to the Android client. I am using Socket and managed to send the data from Client to the Server and also got the Server to send it back to the Client. However, my Client isnt receiving anything, would anyone be kind enough to help me with this problem..?
These are my codes.
Android Client Receive:
class recMsg extends Thread {
#Override
public void run()
{
try
{
Socket socket = new Socket("192.168.68.105", 8123);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String response = in.readLine();
showToast(response);
mTextView.setText((response));
socket.close();
}
catch(Exception e) {}
}
}
Python Server Receive and Send:
import socket
import sys
HOST = '192.168.68.105' # this is your localhost
PORT = 8123
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# socket.socket: must use to create a socket.
# socket.AF_INET: Address Format, Internet = IP Addresses.
# socket.SOCK_STREAM: two-way, connection-based byte streams.
print('socket created')
# Bind socket to Host and Port
try:
s.bind((HOST, PORT))
except socket.error as err:
print('Bind Failed, Error Code: ' + str(err[0]) + ', Message: ' + err[1])
sys.exit()
print('Socket Bind Success!')
# listen(): This method sets up and start TCP listener.
s.listen(10)
print('Socket is now listening')
while True:
conn, addr = s.accept()
print('Connect with ' + addr[0] + ':' + str(addr[1]))
if not conn:
break
buf = conn.recv(4096).decode()
print(buf)
# convert string to byte and send back to android
processedText = "Hello World"
conn.send(processedText.encode())
print("message sent")
s.close()
Related
I want to make connection between raspberry pi and java desktop app using socket the message doesn't send to java it comes NULL and in rpi python, it comes with an exception .what should i do?
server in raspberry pi
import socket
import time
try:
host=''
port=9999
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(5)
print("socket is listening..")
while True:
con,add=s.accept()
print ("connect to ",add)
messag = con.recv(1024)
messag = messag.decode('utf-8')
print ("messag from client ",messag)
print ("done recive..")
time.sleep(2)
if not msgrecv:
break
#send to java
sendMsg = "connection..."
sendMsg =sendMsg.encode()
con.sendall(sendMsg)
print ("Done send ")
con.close()
s.close()
except Exception as e:
print(e)
client in java
try {
Socket soc = new Socket("192.168.1.4", 9999);
DataOutputStream dout = new DataOutputStream(soc.getOutputStream());
DataInputStream in =new DataInputStream(soc.getInputStream());
/////////////////////////////////
while (soc.isConnected()) {
////////////////send
dout.writeUTF("welecome...connect"); //wite string
dout.flush();
//////recive (String)
String msg = in.readUTF();
System.out.println("Server: " + msg);
///////////////
dout.flush();
dout.close();
soc.close();
}
} catch(IOException e) {
System.out.println(e.getMessage());
}
the output
Socket is Listening....
('connect to ', ('...',... ))
messag from Client', u'\x00\x12welecome...connect')
done received! !!
connection Closed...
note : this is exception in python
exception [Errno 9] Bad file descriptor
the message didn't come it come NULL
4.Error in java
run:
null
BUILD SUCCESSFUL (total time: 3 seconds)
The Server receives String requests from the Client and replies with a String message to the Client.
I think the Server has to send the reply differently from how it is right now, so I think this line should be altered: c.sendall('Server: '+str.encode(reply))
Python Server:
# This Python file uses the following encoding: utf-8
import socket
def setupServer(port):
serv=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("socket ist da")
try:
# https://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib
host=socket.gethostbyname(socket.gethostname())
print('Host ip: '+host)
serv.bind((host, port))
except socket.error as msg:
print(msg)
print("socket bind fertig")
return serv
def setupConnection(s):
# Erlaubt 1 Verbindung gleichzeitig
s.listen(1)
connection, address=s.accept()
print("Verbunden zu: "+address[0]+":"+str(address[1]))
return connection
def gET():
reply='GET ausgefuehrt'
return reply
def rEPEAT(te):
reply=te[1]
return reply
def dataTransfer(c,s):
# sendet und erhält Daten bis es stoppen soll
while True:
# Daten erhalten
data=c.recv(1024)#daten erhalten 1024 Buffer size
data=data.decode('utf-8')#nötig?
# Teilt die Datei in Befehl/Command und data auf
dataMessage=data.split(' ',1)
command=dataMessage[0]
if command=='GET'or command=='get':
reply=str(gET())
elif command=='REPEAT'or command=='repeat':
reply=str(rEPEAT(dataMessage))
elif command=='EXIT'or command=='exit':
print("Er ist geganngen")
break
elif command=='KILL'or command=='kill':
print("Server wird geschlossen!")
s.close()
break
else:
print("was?")
reply="Nicht Vorhandener Befehl"
# NAchricht senden
c.sendall('Server: '+str.encode(reply))
print(reply)
print('Klint: '+data)
print("Daten wurden geschickt")
c.close()
def main():
#print("hello")
#host='192.168.1.120'
#host='192.168.2.110'
#print('Host ip: '+str(host))
port=8999
print('Port: '+str(port))
s=setupServer(port)
while True:
try:
conn=setupConnection(s)
dataTransfer(conn,s)
except:
break
if __name__=="__main__":
main()
Java Client Thread:
public class SentThread extends Thread {
Socket socket;
Context cmain;
//boolean stop=false;
SentThread(Socket s,Context c) {
socket = s;
cmain=c;
}
#Override
public void run() {
Log.i("Roman", "run->");
socket=new Socket();
try{
socket.connect(new InetSocketAddress("192.168.2.110", 8999),5000);
}catch (Exception e) {
Log.e("Roman", e.toString());
Toast.makeText(cmain, e.toString(), Toast.LENGTH_SHORT).show();
}
try {
BufferedReader stdIn = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
while (true) {
out.print("Try");
out.flush();
System.out.println("Message sent");
System.out.println("Trying to read...");
String in = stdIn.readLine();
System.out.println(in);
}
} catch (Exception e) {
// TODO: handle exception
Log.e("Roman", e.toString());
}
}
}
The program gets stuck at String in = stdIn.readLine();
I can't figure out a way in which the java application is able to receive the Message from the server, even though the Java program is able to send messages to the server.
Thank you in advance
If you want to communicate with a server using a "line-oriented" protocol (ie, each line sent terminated by \n, reading lines using readline type functions, you should create file objects for the socket in python, and simply use these sock_in and sock_out objects instead of the standard IO channels sys.stdin and sys.stdout in your input/output statements.
socket.makefile() is used to create the sock_in and sock_out file objects. Using encoding='utf-8' specifies the conversion between Python characters and the socket's byte stream.
c.sendall is not used at all. Instead we use print(..., file=sock_out) to transmit the text. flush=True should only be used only on the last output from the server in response to any single command; it may be used on every output statement, but will result in more overhead and lower performance.
Here is a Minimal, Complete, Verifiable example of such as server, in Python3.6. It simply echo's back whatever is sent to it, except for the exit and kill commands. You can test it without involving a Java client using a command like telnet localhost 8889.
server.py:
import socket
class ClientKill(Exception):
pass
def _serviceClient(sock_in, sock_out):
for line in sock_in:
line = line.rstrip('\n')
if line == 'exit':
break
if line == 'kill':
raise ClientKill()
print(line, file=sock_out, flush=True) # Echo back
def serviceClient(client, addr):
with client, client.makefile('r', encoding='utf-8', newline='\n') as sock_in, \
client.makefile('w', encoding='utf-8', newline='\n') as sock_out:
_serviceClient(sock_in, sock_out)
port = 8889
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as listener:
listener.bind(('localhost', port))
listener.listen(0)
try:
while True:
client, addr = listener.accept()
serviceClient(client, addr)
except ClientKill:
print("Server killed by remote client")
On the Java side, change ...
out.print("Try");
out.flush();
... to ...
out.println("Try");
out.flush();
... or the server will keep waiting for the \n character which terminates the line sent from the client.
Also, since we explicitly use utf-8 as the encoding on the python server, you should add the corresponding character encoding in your InputStreamReader and wrap socket.getOutputStream() in a OutputStreamWriter with the same encoding.
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()
I made a python "queue" (similar to a JMS protocol) that will receive questions from two Java clients. The python-server will receive the message from one of the Java clients and the second one will read the question and post an answer. The connection and messaging works, the problem comes when a Java client answers with a String of great length.
The response received by python is incomplete! What is worse, the message is cut at a certain number of characters and always at the same length, but, that number is different if someone else hosts the server. (i.e.: friend1 hosts the server, friend2 sends response, length received: 1380chars. Friend2 hosts the server, friend1 posts the answer, length received: 1431chars) This is the server-side python code:
s = socket.socket()
host = socket.gethostname()
# host = "192.168.0.20"
port = 12345
s.bind((host, port))
s.listen(5)
while True:
c, addr = s.accept()
# print 'Got connection from', addr
message = c.recv(8192) #Is this length a problem?
# print message
message = message.strip()
ipAddress = addr[0]
I read questions here on StackOverflow, that c.recv() should have no problem with a big number of bytes and our response is somewhere close to 1500 characters. This is the java client:
private void openConnection(){
try {
socket = new Socket(HOST, PORT);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
socketPregunta.getInputStream()));
stdIn = new BufferedReader(new InputStreamReader(System.in));
} catch (Exception e) {}
}
public void sendAnswer(String answer) throws IOException{
openConnection();
out.write("PUBLISH-" + answer); //This answer is send incomplete!
out.flush();
closeConnection();
}
Thanks in advance!
From the documentation:
recv(buffersize[, flags]) -> data
Receive up to buffersize bytes from the socket. For the optional
flags argument, see the Unix manual. When no data is available, block
until at least one byte is available or until the remote end is
closed. When the remote end is closed and all data is read, return
the empty string.
So recv() can return fewer bytes than you ask for, which is what's happening in your case. There is discussion of this in the socket howto.
Basically you need to keep calling recv() until you have received a complete message, or the remote peer has closed the connection (signalled by recv() returning an empty string). How you do that depends on your protocol. The options are:
use fixed sized messages
have some kind of delimiter or sentinel to detect end of message
have the client provide the message length as part of the message
have the client close the connection when it has finished sending a message. Obviously it will not be able to receive a response in this case.
Looking at your Java code, option 4 might work for you because it is sending a message and then closing the connection. This code should work:
s = socket.socket()
host = socket.gethostname()
# host = "192.168.0.20"
port = 12345
s.bind((host, port))
s.listen(5)
while True:
c, addr = s.accept()
# print 'Got connection from', addr
message = []
chars_remaining = 8192
recv_buf = c.recv(chars_remaining)
while recv_buf:
message.append(recv_buf)
chars_remaining -= len(recv_buf)
if chars_remaining = 0:
print("Exhausted buffer")
break
recv_buf = c.recv(chars_remaining)
# print message
message = ''.join(message).strip()
ipAddress = addr[0]
I have a client program in java that sends a message "Hello" to python server.
Java code
import java.io.*;
import java.net.*;
public class MyClient {
public static void main(String[] args) {
try{
Socket soc=new Socket("localhost",2004);
DataOutputStream dout=new DataOutputStream(soc.getOutputStream());
dout.writeUTF("Hello");
dout.flush();
dout.close();
soc.close();
}catch(Exception e){
e.printStackTrace();}
}
Python server code
import socket # Import socket module
soc = socket.socket() # Create a socket object
host = "localhost" # Get local machine name
port = 2004 # Reserve a port for your service.
soc.bind((host, port)) # Bind to the port
soc.listen(5) # Now wait for client connection.
while True:
conn, addr = soc.accept() # Establish connection with client.
print ("Got connection from",addr)
msg = conn.recv(1024)
print (msg)
if ( msg == "Hello Server" ):
print("Hii everyone")
else:
print("Go away")
the problem is that java client is able to send a Hello message to the python server but in python side else statement always executes with output " Go away".python version 2.7
Output:
('Got connection from', ('127.0.0.1', 25214))
Hello
Go away
you are getting 'Hello' from client.
if ( msg == "Hello" ):
print("Hii everyone")
else:
print("Go away")
because the string you get on the server side has 2 hidden characters at the beginning, so you must remove these 2 characters before comparing it.
if ( msg[2:] == "Hello" ):
In the Java code you have written
dout.writeUTF("Hello");
But the Python server expects "Hello Server" to print "Hii Everyone".
Change Java Client code to
dout.writeUTF("Hello Server");
Just Use proper syntax. Since you are sending "Hello", "Go away" will be your output.
if ( msg == "Hello Server" ):
print("Hii everyone")
else:
print("Go away")
The problem is that you have to specify the decryption UTF-8 in the Python server and then you should use dout.writeBytes("Hello Server") in the Java client.