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.
Related
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()
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.
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've set up a Raspberry Pi 3 and I want to make a program that sends data whenever a button is pushed on my breadboard. I have a Python server running on my RPi, and a Java client running on my Windows laptop. However, whenever I send data to my Java client, it receives the data, and then for some reason, the RPi server closes the program due to "broken pipe". However this cannot be true, because my Java program receives data from the Pi! The Java program then closes due to the Pi server closing. But from what I've read online, Python's "error 32: broken pipe" is triggered when the remote socket closes prematurely!
What's going on here? Why can't I keep my server running?
(PS: The data that my Java program receives is wrong, but it receives data nonetheless. I send "1\n", and I receive null.)
Here is the code for my RPi server program:
import RPi.GPIO as GPIO
from time import sleep
import atexit
import socket
import sys
GPIO.setmode(GPIO.BOARD)
GPIO.setup(5, GPIO.IN)
GPIO.setup(7, GPIO.OUT)
def cleanup():
print("Goodbye.")
s.close()
GPIO.cleanup()
atexit.register(cleanup)
THRESHOLD= 0.3
host= sys.argv[1]
port= 42844
length= 0
def displayDot():
GPIO.output(7,True)
sleep(0.2)
GPIO.output(7,False)
def displayDash():
GPIO.output(7,True)
sleep(0.5)
GPIO.output(7,False)
try:
print("Initializing connection...")
s= socket.socket(socket.AF_INET,socket.SOCK_STREAM)
serverAddress= (host, 42844)
s.bind(serverAddress)
print("Connection initialized!")
print("Waiting for client...")
s.listen(1) #Puts the server socket into server mode
client, address= s.accept()
print(address)
while True:
if not GPIO.input(5):
length+= 0.1
GPIO.output(7,True)
s.sendall('1\n')
print("HELLO??")
else:
if length!=0:
if length>=THRESHOLD:
print("Dash") #displayDash()
else:
print("Dot") #displayDot()
s.sendall('0')
length= 0
GPIO.output(7,False)
except KeyboardInterrupt:
print("\nScript Exited.")
cleanup();
Here's the code for the Java client program:
import java.net.*;
import java.io.*;
public class MorseClient{
public static void main(String[] args) throws IOException{
String hostname= null; //Initialize
int portNumber= 0; //Initialize
try {
hostname= args[0];
portNumber= Integer.parseInt(args[1]);
}
catch(ArrayIndexOutOfBoundsException aiobe) {
System.err.println("ERROR. Please specify server address, and port number, respectively");
System.exit(1);
}
Socket redoSocket;
long initTime;
try(
Socket echoSocket= new Socket(hostname, portNumber);
PrintWriter out= new PrintWriter(echoSocket.getOutputStream(), true);
BufferedReader in= new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
BufferedReader stdin= new BufferedReader(new InputStreamReader(System.in));
){
redoSocket= echoSocket;
System.out.println("Connection made!");
String userInput= "";
//Order of priority
//Connection time= 0
//Latency= 0
//Bandwidth= 1
redoSocket.setPerformancePreferences(0,0,1);
//Optimizes reliability
redoSocket.setTrafficClass(0x04);
echoSocket.setKeepAlive(true);
String returned= "";
while(true){
returned= in.readLine();
System.out.println(returned);
if(!(returned.isEmpty())){
System.out.println(returned);
System.out.println("YEP");
}
System.out.println(returned);
if(returned==null){
System.out.println("HAHA");
System.out.println("Attempting to reconnect...");
redoSocket= new Socket(hostname,portNumber);
System.out.println(redoSocket.isConnected());
}
}
}
catch(Exception e){
if(e instanceof ConnectException || e instanceof SocketException || e instanceof NullPointerException)
System.err.println("Connection closed by server");
else
System.err.println(e.toString());
}
}
}
The output for the Pi server is:
python ServerMorse.py 192.168.1.101
Initializing connection...
Connection initialized!
Waiting for client...
('192.168.1.14', 58067)
('192.168.1.14', 58067)
Traceback (most recent call last):
File "ServerMorse.py", in <module>
s.sendall('1\n')
File "/usr/lib/python2.7/socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 32] Broken pipe
Goodbye.
And the output for the Java client:
java MorseClient 192.168.1.101 42844
Connection made!
null
Connection closed by server
Good lord, why are you writing a server with sockets? Use Flask.
http://flask.pocoo.org/
Also, pretty sure s should not be sending all. It should be like this:
conn, addr = server.accept()
conn.sendall(.... # <- this is what sends
Here is some sample code from a server I wrote with sockets once..might be useful:
def server():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
address = ('127.0.0.1', 5020)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(address)
server.listen(1)
conn, addr = server.accept()
...
...
conn.sendall(response_ok(some_stuff))
...
conn.close()
(response_ok is a function I wrote)
I've got a server written in python running twisted (twistd), and a client written in Java. The idea is that we'll be able to send Strings of encoded data between clients via this server. However, we're finding that clients never send a string to the server (it's never logged on the server as having been received). Does anyone have any ideas?
I've included the code for the client and server below.
Client:
Socket s = new Socket("localhost", 1025);
InputStream is = s.getInputStream();
OutputStream os = s.getOutputStream();
System.out.println("Before Read");
System.out.println(is.read());
System.out.println("After Read");
os.write("Hello from java!".getBytes());
Server:
class MyChat(basic.LineReceiver):
__opponent = None
def connectionMade(self):
print "SLOG"
self.factory.clients.append(self)
print "SLOG 1"
self.factory.notInGame.append(self)
print "SLOG 2"
while (len(self.factory.notInGame) >= 2):
x = self.factory.notInGame.pop(0)
y = self.factory.notInGame.pop(0)
x.__opponent = y
y.__opponent = x
print "SLOG FINISH YAY"
def connectionLost(self, reason):
print "SLOG Lost a client!"
self.factory.clients.remove(self)
if (self.__opponent == None):
self.factory.notInGame.remove(self)
else:
self.__opponent.__opponent = None
self.factory.notInGame.append(self.__opponent)
def lineReceived(self, data):
print "SLOG Sender data received"
if self.__opponent == None:
self.transport.write("E0") # not in game
print "SLOG E0"
return
self.__opponent.transport.write(data)
from twisted.internet import protocol
from twisted.application import service, internet
factory = protocol.ServerFactory()
factory.protocol = MyChat
factory.clients = []
factory.notInGame = []
application = service.Application("chatserver")
#internet.TCPServer(1025, factory).setServiceParent(application)
reactor.listenTCP(1025, factory)
Any help appreciated - thanks
Sam
LineReceiver accumulates data in a buffer and calls the lineReceived callback when it receives a full line. By default lines are terminated by the byte sequence "\r\n".
It looks like your Java application sends "Hello from java!". Since it does not send "\r\n" LineReceiver never decides to call lineReceived.