SimpleHTTPServer "server forever" blocking rest of script - python

Below is my script. It creates a directory, detects an arduino device, continuously writes output from it to a text file, and serves that file in a local server. From what I can tell (and have read), this line:
httpd.serve_forever()
causes nothing after to be processed. The text file never get's written to. If I move httpd.serve_forever() line down further, it'll process everything up to that point, so this does appear to reaffirm this theory. How can I do what I need? Is it clear where I'm going wrong?
import serial
import serial.tools.list_ports
import os
import SimpleHTTPServer
import SocketServer
import sys,os
fileDir = os.path.dirname(os.path.realpath('__file__'))
try:
os.makedirs(os.path.join(fileDir, 'log'))
except OSError:
if not os.path.isdir(os.path.join(fileDir, 'log')):
raise
directory = os.path.join(fileDir, 'log')
log = os.path.join(directory, 'log.txt')
os.chdir(directory)
PORT = 8080
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
httpd.serve_forever()
def get_ports():
ports = serial.tools.list_ports.comports()
return ports
def findArduino(portsFound):
commPort = 'None'
numConnection = len(portsFound)
for i in range(0,numConnection):
port = foundPorts[i]
strPort = str(port)
if 'Arduino' in strPort:
splitPort = strPort.split(' ')
commPort = (splitPort[0])
return commPort
foundPorts = get_ports()
connectPort = findArduino(foundPorts)
if connectPort != 'None':
ser = serial.Serial(connectPort,baudrate = 9600, timeout=1)
while 1:
if ser.inWaiting():
with open(log, "w") as txtfile:
x=ser.readline()
txtfile.write(x)
txtfile.flush()
if x=="\n":
txtfile.seek(0)
txtfile.truncate
txtfile.flush()
ser.close()
else:
print('Connection Issue!')
print('DONE')

Related

socket TCP python file transfer - while True loop don't exit

I have made a socket TCP for file transfer using python. Everything is ok and I can receive the file from the server socket but the problem is that I can not exit the while True loop of client socket, even I put a break to exit this loop.
Someone can help me point out what is my mistake pls!
The loop run until to print "File Receiving..." and never exit, but I can receiver the file completely.
Thank you very much
Socket Client:
import socket
import os
import unicodedata
from tqdm import tqdm
SIZE = 1024*4
FILENAME = "xyz.bin"
HOST = "127.0.0.1"
PORT = 8001
client_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_address = (HOST, PORT)
client_tcp.connect(tcp_server_address)
try:
for i in range(1,11):
texte = "PING\n"
client_tcp.send(texte.encode())
data=client_tcp.recv(1024).decode('utf-8')
print("Received:", str(data))
texte = "ABC"
client_tcp.send(texte.encode())
data=client_tcp.recv(1024)
print('Server: ', data.decode("utf8"))
with open(f"recv_{FILENAME}", "wb") as f:
while True:
data = client_tcp.recv(SIZE)
if not data:
#print("not data")
break
f.write(data)
print("File Receiving...")
print("Received:", str(data))
client_tcp.send("Data received.".encode("utf-8"))
f.close()
finally:
client_tcp.close()
print("File Received")
The keyword with will automatically close the file so no need of f.close()

Python socket getting the error “connection refused error 111”

I have a problem connecting with the socket.
I wrote a code whose purpose is to get the serial number of the hard disk from a client and send it to the server.
If I run the server and the client code on my local machine, it works fine.
When I try to run the server on the real server and the client on the real client (2 different machines) I’m getting the error:
“Connection refused error 111”
This is my client code:
#!/usr/bin/python3
import os, socket
from time import sleep
def serialNumber():
"""Find the product serial number"""
serialtest = "smartctl -a -i /dev/sda2 > /root/Desktop/serialTest.txt"
grepp = "grep 'Serial Number:' /root/Desktop/serialTest.txt > /root/Desktop/NewserialTest.txt"
sedd = "sed -i 's/Serial Number: //g' /root/Desktop/NewserialTest.txt"
os.system(serialtest)
os.system(grepp)
os.system(sedd)
try:
with open (r"/root/Desktop/NewserialTest.txt","r") as data:
global newserial
newserial = data.readline().strip()
except:
return "File not found!"
try:
os.rename(r'/root/Desktop/NewserialTest.txt',rf'/root/Desktop/{newserial}.txt')
os.remove(r"/root/Desktop/serialTest.txt")
except:
return "File not found!"
return ""
print(serialNumber())
try:
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ip = socket.gethostname()
port = 5555
s.connect((ip,port))
except socket.error as e:
print(f"UNABLE to connect! you got error:\n{e}.")
exit(-1)
try:
with open(rf'/root/Desktop/{newserial}.txt', "rb") as fd:
toSend = fd.read()
s.send(toSend)
except socket.error as e:
print(f"you got error:\n{e}.")
This is my Server code:
#!/usr/bin/python3
import os, socket
from _thread import *
server_socket = socket.socket()
host = socket.gethostname()
port = 5555
try:
server_socket.bind((host, port))
except socket.error as e:
print(f"You have a error:\n{str(e)}")
print("\nWaiting for connection....\n")
server_socket.listen(100)
while True:
# Recive the serial number from the client
sc, address = server_socket.accept()
print(address)
f = open(r'/root/Desktop/LAB_Test/NewserialTest.txt' ,'wb') #open in binary
while (True):
l = sc.recv(1024)
f.write(l)
if not l:
break
f.close()
sc.close()
try:
with open (r'/root/Desktop/LAB_Test/NewserialTest.txt',"r") as data:
global newserial
newserial = data.readline().strip()
except:
print("File not found!")
os.rename(r'/root/Desktop/LAB_Test/NewserialTest.txt',rf'/root/Desktop/LAB_Test/{newserial}.txt')
what could be the problem?
I changed the bind to 0.0.0.0, and now it works.

Python 3: Sending files through socket. (Client-Server Program)

I am having the above issue. The client is suppose to ask for a filename and send the file name to the server after which the server will open the file and display it. Problem is that the server isn't opening the file and displaying it.
Below is the client.
#!/usr/bin/env python3
import socket, os.path, datetime, sys
def Main():
host = '127.0.0.1'
port = 50001
s = socket.socket()
s.connect((host, port))
Filename = input("Type in ur file ")
s.send(Filename.encode('utf-8'))
data = s.recv(1024).decode('utf-8')
s.close()
if __name__ == '__main__':
Main()
Below is the server
#!/usr/bin/env python3
import socket
import os
import sys
def Main():
host = '127.0.0.1'
port = 50001
s = socket.socket()
s.bind((host,port))
print("server Started")
s.listen(1)
c, addr = s.accept()
print("Connection from: " + str(addr))
while True:
data = c.recv(1024).decode('utf-8')
myfile = open(data, "r")
if not data:
break
print("from connected user: " + myfile)
c.close()
if __name__ == '__main__':
Main()
I've made few minimal adjustments to your code with which it runs as so that server.py continuously listens on a given port and sends back data which each invocation of client.py asks for.
server.py
#!/usr/bin/env python3
import socket
import os
import sys
def Main():
host = '127.0.0.1'
port = 50001
s = socket.socket()
s.bind((host,port))
print("server Started")
s.listen(1)
while True:
c, addr = s.accept()
print("Connection from: " + str(addr))
filename = ''
while True:
data = c.recv(1024).decode('utf-8')
if not data:
break
filename += data
print("from connected user: " + filename)
myfile = open(filename, "rb")
c.send(myfile.read())
c.close()
if __name__ == '__main__':
Main()
client.py
#!/usr/bin/env python3
import socket, os.path, datetime, sys
def Main():
host = '127.0.0.1'
port = 50001
s = socket.socket()
s.connect((host, port))
Filename = input("Type in ur file ")
s.send(Filename.encode('utf-8'))
s.shutdown(socket.SHUT_WR)
data = s.recv(1024).decode('utf-8')
print(data)
s.close()
if __name__ == '__main__':
Main()
And now a bit of explanation.
On the server side. The outer loop accepts a connection, then reads from the connection until done (more on this later). Prints your debugging info, but note you were trying to print the file object and not the filename (which would fail trying to concatenate). I also open the file in binary mode (that way I can skip the str -> bytes translation.
On the client side. I've added closing the writing end of the socket when the file has been sent. Note you might want to use sendall instead of send for this use case: check those docs links for details. And I've added a print for the incoming data.
Now that bit with shutting down the writing end in the client and the inner loop reading (and also related to the sendall hint. Which BTW also holds true for the server side, otherwise you should loop, as you might see your content truncated; other option is to also have a sending loop.). Stream sockets will guarantee you get your bytes in in order you've send them. On itself it has no idea whether your message is complete and it also does not guarantee in how many and how large chunks will the data be sent and received (resp.).
The inner loop of server keep reading until we see an EOF (we've receive zero length string in python socket). This would happen (be returned by recv when the remote socket (or at least its writing end) has been shut down. Since we still want to reuse the connection, we only do that on the sending end in the client. Hope this helps you to move ahead.

Save logs - SimpleHTTPServer

How can I save the output from the console like
"192.168.1.1 - - [18/Aug/2014 12:05:59] code 404, message File not found"
to a file?
Here is the code:
import SimpleHTTPServer
import SocketServer
PORT = 1548
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
print "serving at port", PORT
httpd.serve_forever()
BaseHTTPRequestHandler.log_message() prints all log messages by writing to sys.stderr. You have two choices:
1) Continue using BaseHTTPRequestHandler.log_message(), but change the value of sys.stderr:
import SimpleHTTPServer
import SocketServer
PORT = 1548
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
print "serving at port", PORT
import sys
buffer = 1
sys.stderr = open('logfile.txt', 'w', buffer)
httpd.serve_forever()
2) Create a new xxxRequestHandler class, replacing .log_message():
import SimpleHTTPServer
import SocketServer
import sys
PORT = 1548
class MyHTTPHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
buffer = 1
log_file = open('logfile.txt', 'w', buffer)
def log_message(self, format, *args):
self.log_file.write("%s - - [%s] %s\n" %
(self.client_address[0],
self.log_date_time_string(),
format%args))
Handler = MyHTTPHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
print "serving at port", PORT
httpd.serve_forever()
I have used BaseHTTPServer instead of SimpleHTTPServer.
There you go:
#!/usr/bin/python
from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
PORT_NUMBER = 5451
#This class will handles any incoming request from
#the browser
class myHandler(BaseHTTPRequestHandler):
#Handler for the GET requests
def do_GET(self):
self.send_response(200)
#self.send_header('Content-type','text/html')
self.end_headers()
text_file = open("ip.txt", "a")
text_file.write(str(self.client_address) + "\n")
text_file.close()
# Send the html message
#self.wfile.write("Hello World !")
return
try:
#Create a web server and define the handler to manage the
#incoming request
server = HTTPServer(('', PORT_NUMBER), myHandler)
print 'Started httpserver on port ' , PORT_NUMBER
#Wait forever for incoming htto requests
server.serve_forever()
except KeyboardInterrupt:
print '^C received, shutting down the web server'
server.socket.close()

Python : How to handle multiple clients and a server

I am implementing a program with a server and multiple clients. All clients send data to the server and a server check out the step of each client. If all client's steps are the same, a server sends new data to all clients to do next step. And it continues this procedure again and again.
However, when I run my program, it cannot communicate each other. Here are my code. Would you give me some hints?
client & server
#client
from socket import *
from sys import *
import time
import stat, os
import glob
# set the socket parameters
host = "localhost"
port = 21567
buf = 1024
data = ''
addr = (host, port)
UDPSock = socket(AF_INET, SOCK_DGRAM)
UDPSock.settimeout(100)
def_msg = "=== TEST ==="
#FILE = open("test.jpg", "w+")
FILE = open("data.txt","w+")
while (1):
#data, addr = UDPSock.recvfrom(buf)
print "Sending"
UDPSock.sendto(def_msg, addr)
#time.sleep(3)
data, addr = UDPSock.recvfrom(buf)
if data == 'done':
FILE.close()
break
FILE.write(data)
print "Receiving"
#time.sleep(3)
UDPSock.close()
# server program for nvt
from socket import *
import os, sys, time, glob
#import pygame
import stat
host = 'localhost'
port = 21567
buf = 1024
addr = (host, port)
print 'test server'
UDPSock = socket(AF_INET, SOCK_DGRAM)
UDPSock.bind(addr)
msg = "send txt file to all clients"
#FILE = open("cam.jpg", "r+")
FILE = open("dna.dat","r+")
sending_data = FILE.read()
FILE.close()
tmp_data = sending_data
while (1):
#UDPSock.listen(1)
#UDPSock.sendto(msg, addr)
#FILE = open("gen1000.dat","r+")
#sending_data = FILE.read()
#FILE.close()
#print 'client is at', addr
data, addr = UDPSock.recvfrom(buf)
#time.sleep(3)
print data
#msg = 'hello'
#
tmp, sending_data = sending_data[:buf-6], sending_data[buf-6:]
if len(tmp) < 1:
msg = 'done'
UDPSock.sendto(msg, addr)
print "finished"
sending_data = tmp_data
UDPSock.sendto(tmp, addr)
print "sending"
#time.sleep(3)
UDPSock.close()
A server must perform the sequence socket(), bind(), listen(), accept() (possibly repeating the accept() to service more than one client), while a client only needs the sequence socket(), connect().
Your missing listen() i saw first. Listen for connections made to the socket.
More on this here: link text
Look at this: http://heather.cs.ucdavis.edu/~matloff/Python/PyNet.pdf
It's a very good Python networking tutorial including working examples of a client and server. Now, I'm not an expert on this, but it looks to me like your code is overcomplicated. And what's the deal with all the commented-out lines?
Quote from question:
#UDPSock.listen(1)
#UDPSock.sendto(msg, addr)
#FILE = open("gen1000.dat","r+")
#sending_data = FILE.read()
#FILE.close()
End quote
Those look like some pretty important lines to me.
Also, make sure the computers are connected. From a prompt run:
ping [IP]
where [IP] is the IP address of the other machine(Note: if you're not connected to the same LAN, this becomes much harder as you might then need port forwarding and possibly static IPs).

Categories

Resources