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)
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)
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.
As the name suggest the client sends null to the server. i cant figure out why
Python client
import socket
HOST = "localhost"
PORT = 5000
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
dict = {
0: "doug",
1: "korg",
2: "stefan",
}
for x in range(0, 3):
if x == 3:
sock.sendall("Bye\n")
print(sock.recv(1024))
sock.sendall(b"{}\n".format(dict.get(x)))
print(dict.get(x))
print(sock.recv(1024))
Java server:
public void run() {
String fromClient;
String toClient;
try {
ServerSocket server = new ServerSocket(5000);
System.out.println("wait for connection on port 5000");
boolean run = true;
Socket client = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
while (run) {
System.out.println("got connection on port 5000");
fromClient = in.readLine();
System.out.println("received: " + fromClient);
if (fromClient.equals("Bye")) {
toClient = "Aight later man";
System.out.println("send eyB");
out.println(toClient);
client.close();
System.out.println("socket closed");
break;
}
out.println("cool next User Please");
}
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
}
}
while the first 3 strings are being send from the client to the server and the server responds back, when Bye is send the server receives null and throws a nullpointerexception.
my code is based on this post.
Communication between python client and java server
the problem exist in String as ByteString form.
output of server:
wait for connection on port 5000
got connection on port 5000
received: doug
got connection on port 5000
received: korg
got connection on port 5000
received: stefan
got connection on port 5000
Exception in thread "Thread-0" java.lang.NullPointerException
at Jserver.run(Jserver.java:28)
received: null
Process finished with exit code 0
output of client:
doug
cool next User Please
korg
cool next User Please
stefan
cool next User Please
Your issue is caused in the python code, which never sends the "bye" command.
The bug in the python code:
Your python code loops from 0 (inclusive) to 3 (exclusive), since the 3 is excluded, the code never goes into the "bye" block, and never sends this. (print x to confirm this)
Place the "bye" code after the loop.
for x in range(0, 3):
sock.sendall(b"{}\n".format(dict.get(x)))
print(dict.get(x))
print(sock.recv(1024))
sock.sendall("Bye\n")
print(sock.recv(1024))
The bug in the Java code
Yes, there is also a bug in the Java code, mainly that it does not deal with stream closures properly.
When the Python program is being shutdown at the end of the code, the Java program will receive a clean exit, this is an exception-less way of closing the socket, and will result in readLine returning a null value.
This null then causes the following exception:
Exception in thread "Thread-0" java.lang.NullPointerException
Since seeing an null value means the socket is closed, you can also thread this as either a proper "bye" response or as a error condition.
if (fromClient == null || fromClient.equals("Bye")) {
Well, basically you have answer in you logs
Exception in thread "Thread-0" java.lang.NullPointerException
at Jserver.run(Jserver.java:28)
received: null
So fromClient variable is null. You can add simple check for it to avoid such kind of exceptions and skip loop continuation.
if (fromClient == null) {
continue;
}
I have written a code in java to interface my computer with a transmitter a transmitter device, with a communication board already implemented and ready to connect via TCP/IP to any server with a specific address IP (say 192.168.2.2) and listening to a specific port number (say 4000).
I followed the exact strep how to create a server side application in Java offering a that listening port, so that I can connect to that transmitter.
I don't understand why when I try to debug the code, it blocks a the line clientSocket = serverSocket.accept(), and throws a timeout exception.
Could someone help me find out where the error might be in my code?
Any help would be greatly appreciated.
Thanks.
Here is the code:
public class Server {
public static void main(String[] args) {
// TODO Auto-generated method stub
//Declares server and client socket, as well as the input and the output stream
ServerSocket serverSocket = null;
Socket clientSocket = null;
PrintWriter out;
//BufferedReader in;
BufferedReader in;
try{
InetAddress addr = InetAddress.getByName("192.168.2.2");
//Opens a server socket on port 4000
serverSocket = new ServerSocket(4000) ;
//Sets the timeout
serverSocket.setSoTimeout(30000);
System.out.println("Server has connected");
//Create a connection to server
System.out.println("Server listening connection from client ....");
//Listens and waits for client's connection to the server
clientSocket = serverSocket.accept();
// Creates input and output streams to socket
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//Reads response from socket
while((in.readLine())!= null ){
System.out.println ( in.readLine() );
}
System.out.println ( "Closing connection ....");
//Terminates connection
clientSocket.close();
serverSocket.close();
System.out.println("Connecton successfully closed");
}
catch(IOException e){
System.out.println(e);
}
}
}
Could someone help me find out where the error might be in my code?
There is no error in your code that could cause this problem. Clearly you haven't configured the device to connect to this server correctly, or the device isn't running, or it isn't connecting, or there is a firewall in the way. Investigate that.
However:
InetAddress addr = InetAddress.getByName("192.168.2.2");
What is this for? It isn't used.
System.out.println("Server has connected");
This is simply not true. The server hasn't connected. At this point all it has done is create a listening socket.
while((in.readLine())!= null ){
Here you are reading a line and throwing it away.
System.out.println ( in.readLine() );
Here you are printing every second line, having thrown every odd line away. The correct way to write this loop is:
String line;
while ((line = in.readLine()) != null)
{
System.out.println(line);
}
Note also that this server will service exactly one client and then exit. There should be a loop around everything from accept() to clientSocket.close(), and if there are multiple devices it should start a new thread per accepted socket to handle the I/O.
You specified timeout of 30 seconds, didn't you? :
serverSocket.setSoTimeout(30000);
So after 30 seconds, no matter whether stopped in debugger or running, this will timeout and throw exception.
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.