How can I send a HTML page which contains pictures? - python

I've written a TCP server, which functions perfectly with web pages which only contain text, but I cant seem to send HTML files which contain pictures. How am I supposed to do it?
DIR = "D:/wwwroot/"
SERVER = ("server_address", 8820) #server_address replaced with my IP
PHRASE_CHART = "D:/wwwroot/phrase_chart.txt"
CONTENT_TYPE_CHART = "D:/wwwroot/content_type_chart.txt"
DEFAULT_PAGE = "D:/wwwroot/main.html"
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(SERVER)
client_counter = 0
while client_counter <= 10:
server_socket.listen(1)
(client_socket, client_address) = server_socket.accept()
client_counter += 1
while True:
try:
request = client_socket.recv(1024)
request = request[0:request.find("/r/n/r/n")]
if request[0:3] == "GET":
file_name = request[5: request.find("HTTP/1.1") - 1]
if os.path.isfile(DIR + file_name):
page = open(DIR + file_name)
data = ""
for line in page:
data += line
client_socket.send(data)
elif file_name == "":
page = open(DEFAULT_PAGE)
data = ""
for line in page:
data += line
client_socket.send(data)
else:
client_socket.send("")
else:
client_socket.close()
except socket.error:
break
client_socket.close()
server_socket.close()

Related

Python client socket not receiving data from TCP server

I'm trying to build a fake money transfer program with sockets in python. Everything is working perfectly except the "name" and "amount" transfer from the server to the client. When someone clicks receive on the client interface, the server is supposed to send the client the name of the person who sent the money and the amount. The problem is that the client is not receiving the data sent from the server. When you click the "receive" button, the interface just freezes then crashes. From the debugging I've done, I'm pretty sure the server is sending the name and amount, but the client is not receiving it. I honestly have no idea why it's not working. Everything I did should work like it has numerous other times throughout the program. This one has got me stumped.
Any help would be great. Thanks! 😁
[CODE]
Server.py:
import socket
import threading
HOST = '192.168.1.6'
PORT = 9090
def client_fun(client, addr):
global transfers
print(f"{addr} just connected!")
connected = True
while connected:
msg = client.recv(1024).decode('utf-8')
if msg == "RECEIVE_CHECK":
usrn = client.recv(1024).decode('utf-8')
transfers_ = open("transfers.txt", "r")
transfers = str(transfers_.readlines())
transfers = transfers.split("+")
transfers[0] = transfers[0].replace("[", "")
transfers[0] = transfers[0].replace("'", "")
transfers.pop()
names = []
for tran in transfers:
tran_ = tran.split("-")
i = 0
while i <= len(tran):
names.append(tran_[2])
i += 1
if usrn in names:
client.send("OK".encode('utf-8'))
else:
client.send("NO".encode('utf-8'))
if usrn in names:
for tran in transfers:
tran_ = tran.split("-")
if usrn == tran_[2]:
name = str(tran_[0])
amount = str(tran_[1])
client.send(name.encode('utf-8'))
client.send(amount.encode('utf-8'))
account_file = usrn + "_" + "account.txt"
account_r = open(account_file, "r")
account_r = str(account_r.readlines())
account_r = account_r.replace(']', '')
account_r = account_r.replace('[', '')
account_r = account_r.replace("'", "")
try:
account_r = int(account_r)
except:
print("Can't Convert Str to Int!")
break
new_amount = int(tran_[1]) + account_r
account_w = open(account_file, "w")
account_w.write(str(new_amount))
account_w.close()
tran = tran + "+"
transFers_ = open("transfers.txt", "r")
transFers = str(transFers_.readlines())
transFers_.close()
transFers = transFers.replace(']', '')
transFers = transFers.replace('[', '')
transFers = transFers.replace("'", "")
transFers = transFers.replace(tran, '')
transFers_ = open("transfers.txt", 'w+')
transFers_.write(transFers)
transFers_.close()
print("Excepted!")
else:
print("Nothing Here!")
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST, PORT))
server.listen()
print("Server is listening!")
while True:
c_socket, address = server.accept()
thread = threading.Thread(target=client_fun, args=(c_socket, address))
thread.start()
Client.py:
import socket
HOST = '192.168.1.6'
PORT = 9090
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def receive(usrn):
socket.send("RECEIVE_CHECK".encode('utf-8'))
socket.send(usrn.encode('utf-8'))
c = socket.recv(1024).decode('utf-8')
if c == "OK":
try:
print("Trying to except....")
name = socket.recv(2000).decode('utf-8')
amount = socket.recv(2000).decode('utf-8')
print("Excepted!")
messagebox.showwarning("Continue?", f"{name} has sent you ${amount}", icon="question")
messagebox.showwarning("Info", f"${amount} has just been transferred to your account!", icon="info")
menu(usrn)
except:
print("Error!")
else:
print("Nothing Today!")

Receive multiple files simultaneously

I wrote a script in Python 3.8.6 to send and receive files between different devices. I am sending and receiving files normally, the problem happens when I receive multiple simultaneous connections from different devices.
I configured the script to save the files in folders named with the address of the device that sends the file and what is happening is that when several devices send files at the same time, files from one device go to another folder, randomly. The files are mixed.
I have an idea of why it is happening but not how to solve it.
I thought as an alternative to receive only one connection at a time.
But I don't know how to do this.
sendfile.py
def conectividade(host="192.168.0.13", porta=1218, timeout=5):
while True:
try:
socket.setdefaulttimeout(timeout)
socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, porta))
return True
except Exception:
return False
# Function that sends the collected data.
def coleta():
total = []
conectividade()
conect = conectividade()
if conect == False:
print("\nConnectivity is",conect)
pass
else:
data_hoje = datetime.now().strftime('%Y-%b-%d')
direct = f".\\{data_hoje}\\"
arquivos = os.listdir(direct)
for arquivo in arquivos:
try:
sock = socket.socket()
host = "192.168.0.13"
porta = 1218
print("Connectivity is", conect)
sock.connect((host, porta))
total += arquivo.split(',')
sock.send(str.encode(arquivo))
arquivo = str.encode(direct + arquivo)
with open(arquivo, "rb") as file:
data = file.read(1024)
resposta = sock.recv(1024)
if resposta == b'Waiting file':
file_size = os.path.getsize(arquivo)
print(b"sending " + arquivo)
print(file_size,"kb")
sock.send(bytes(str(file_size),'utf-8'))
resposta = sock.recv(1024)
if resposta == b'Waiting...':
while data:
sock.send(data)
data = file.read(1024)
if not data:
print(f"**Sending Complete**\n")
sock.close()
# Delete files after uploads
if total == arquivos:
print(f"Uploaded files:\n",total)
except socket.error:
print("\nSocket Error\n")
receive.py
data_hoje = datetime.now().strftime('%Y-%b-%d')
sock = socket.socket()
host ='192.168.0.13'
porta = 1218
sock.bind((host, porta))
sock.listen(10)
total = []
while True:
conn, addr = sock.accept()
pasta = ".\\" + addr[0].replace('.','_')
subpasta = pasta + "\\" + data_hoje
if os.path.exists(pasta) == False:
os.makedirs(f'{pasta}')
if os.path.exists(subpasta) == False:
os.makedirs(f'{subpasta}')
data = conn.recv(1024)
while data == b'':
conn.close()
conn, addr = sock.accept()
data = conn.recv(1024)
if data == b'Finalizando socket':
print("Finalizando conexĂŁo com " + addr[0])
conn.close()
sock.close()
total += data.decode().split(',')
name_file = total[-1]
with open(f"{subpasta}\\{name_file}", "wb") as file:
conn.send(b"Waiting file")
data = conn.recv(1024)
tamanho = data.decode('utf-8')
file_size = int(tamanho)
if file_size != 0:
conn.send(b"Waiting...")
print("HOST <--> " + addr[0] + f" Download de {name_file} - {tamanho} kb")
while data:
data = conn.recv(1024)
file.write(data)
conn.close()
In receive.py you have:
conn, addr = sock.accept()
# [...]
while data == b'':
conn.close()
conn, addr = sock.accept()
data = conn.recv(1024)
The client that connects on the first accept() may be different from the client that connects on the accept() inside the cycle, which could lead to the files mixing up as you described. You should re-write it with a single accept(), to guarantee the whole processing is done for the same client. This approach is described in TCP/IP Client and Server - PyMOTW-3.
Modified receive.py:
data_hoje = datetime.now().strftime("%Y-%b-%d")
sock = socket.socket()
host = "192.168.0.13"
porta = 1218
sock.bind((host, porta))
sock.listen(10)
total = []
try:
while True:
conn, addr = sock.accept()
try:
pasta = ".\\" + addr[0].replace(".", "_")
subpasta = pasta + "\\" + data_hoje
if os.path.exists(pasta) is False:
os.makedirs(f"{pasta}")
if os.path.exists(subpasta) is False:
os.makedirs(f"{subpasta}")
data = b""
while data == b'':
data = conn.recv(1024)
if data == b"Finalizando socket":
print("Finalizando conexĂŁo com " + addr[0])
continue
total += data.decode().split(",")
name_file = total[-1]
with open(f"{subpasta}\\{name_file}", "wb") as file:
conn.send(b"Waiting file")
data = conn.recv(1024)
tamanho = data.decode("utf-8")
file_size = int(tamanho)
if file_size != 0:
conn.send(b"Waiting...")
print(
"HOST <--> " + addr[0] + f" Download de {name_file} - {tamanho} kb"
)
while data:
data = conn.recv(1024)
file.write(data)
finally:
conn.close()
finally:
sock.close()
Basically, what was causing the error was the conectividade() function recursively in the original script.
so I needed...
while True:
conn.close()
conn, addr = socket.accept()
data = conn.recv
What caused the files to mix, as said by fzdb ...
How was the new script ...
sendfile.py
import socket
import os
from datetime import datetime
def coleta():
total = []
data_hoje = datetime.now().strftime('%Y-%b-%d')
direct = f".\\{data_hoje}\\"
arquivos = os.listdir(direct)
for arquivo in arquivos:
try:
sock = socket.socket()
host = "192.168.0.13"
porta = 1218
print("Connectivity is",)# conect)
sock.connect((host, porta))
total += arquivo.split(',')
sock.send(str.encode(arquivo))
arquivo = str.encode(direct + arquivo)
with open(arquivo, "rb") as file:
data = file.read(1024)
resposta = sock.recv(1024)
if resposta == b'Waiting file':
file_size = os.path.getsize(arquivo)
print(b"sending " + arquivo)
print(file_size,"kb")
sock.send(bytes(str(file_size),'utf-8'))
resposta = sock.recv(1024)
if resposta == b'Waiting...':
while data:
sock.send(data)
data = file.read(1024)
if not data:
sock.close()
print(f"**Sending Complete**\n")
if total == arquivos:
print(f"Uploaded files:\n",total)
except socket.error:
print("\nSocket Error\n")
receive.py
import socket
import os
from datetime import datetime
data_hoje = datetime.now().strftime('%Y-%b-%d')
host ='192.168.0.13'
porta = 1218
sock.bind((host, porta))
sock.listen(10)
total = []
while True:
conn, addr = sock.accept()
pasta = ".\\" + addr[0].replace('.','_')
subpasta = pasta + "\\" + data_hoje
if os.path.exists(pasta) == False:
os.makedirs(f'{pasta}')
if os.path.exists(subpasta) == False:
os.makedirs(f'{subpasta}')
data = conn.recv(1024)
if data == b'':
conn.close()
total += data.decode().split(',')
name_file = total[-1]
try:
with open(f"{subpasta}\\{name_file}", "wb") as file:
conn.send(b"Waiting file")
data = conn.recv(1024)
tamanho = data.decode('utf-8')
file_size = int(tamanho)
if file_size != 0:
conn.send(b"Waiting...")
print("HOST <--> " + addr[0] + f" Download de {name_file} - {tamanho} bytes")
while data:
data = conn.recv(1024)
file.write(data)
except:
pass
Thank you!
For those who want to help with the original code ...
I have problems with NumPad on pynput
https://github.com/gconelhero/Keylogger

Type Error using Socket communication even while decoding to byte string

Hello I got a problem with a type error I cant get rid off.
I have build a server named processA.py and a client processB.py
I start the server calling processA and it starts up
I start the client calling processB and it starts up
Now I input the name of the file I want to send over a socket.
The image must be in the same folder as the programms.
You can use the sample code from below for reproducing the error.
I choose: lena.jpg
I get an error in line 15, in of my processA.py:
sock.send("EXISTS" + str(os.path.getsize(filenameByte))) TypeError: a
bytes-like object is required, not 'str'
processA.py
'''
Created on 29 Nov 2017
#author: Poor Student
'''
import numpy
import socket
import threading
import os
def RtrFile(name, sock):
filenameByte = sock.recv(1024)
filenameStr = filenameByte.decode('ascii')
if os.path.isfile(filenameStr):
sock.send("EXISTS" + str(os.path.getsize(filenameByte)))
userResponse = sock.recv(1024)
if userResponse[:2] == 'OK':
with open(filenameByte, 'rb') as f:
bytesToSend = f.read(1024)
sock.send(bytesToSend)
while bytesToSend != "":
bytesToSend = f.read(1024)
sock.send(bytesToSend)
else:
sock.send("ERR")
sock.close()
def Main():
host = "127.0.0.1"
port = 5000
s = socket.socket()
s.bind((host,port))
s.listen(5)
print("server started.")
while True:
c, addr =s.accept()
print("client connected ip:< " + str(addr) +">")
t = threading.Thread(target = RtrFile, args=("rtrThread",c))
t.start()
s.close()
if __name__ == "__main__":
Main()
processB.py
'''
Created on 29 Nov 2017
#author: Poor Student
'''
import socket
def Main():
host = "127.0.0.1"
port = 5000
s = socket.socket()
s.connect((host,port))
filename = input("Filename? -> ")
if filename != "q":
s.send(filename.encode())
data = s.recv(1024)
if data[:6] == "EXISTS":
filesize = int(data[6:])
message = input("File Exists, " +str(filesize) + "Bytes, download? (Y/N)? ->")
if message == "Y" or message =="y":
s.send("OK")
f = open("new_" + filename, "wb")
data = s.recv(1024)
totalRecv = len(data)
f.write(data)
while totalRecv < filesize:
data = s.recv(1024)
totalRecv += len(data)
f.write(data)
print("(0:.f)".format((totalRecv)/float(filesize))*100 +"done")
print("Download Complete")
else:
print("File does not exists")#
s.close()
if __name__ == "__main__":
Main()
I found an answer. In python 3 you have allways convert your Strings to byte strings when sending them. After sending them to the receiver you have to decode them again and this must be done for the hole communication which is why the error allways shows up in the same module.
Process A:
'''
Created on 29 Nov 2017
#author: Happy student
'''
import numpy
import socket
import threading
import os
from idlelib.IOBinding import encoding
def RtrFile(name, sock):
filenameByte = sock.recv(1024)
filenameStr = filenameByte.decode('ascii')
print("FilenameStr",filenameStr)
if os.path.isfile(filenameStr):
print("Type:",type(filenameByte))
print(os.path.getsize(filenameByte))#
sendStr = "EXISTS" + str(os.path.getsize(filenameByte))
#Convert the string to byte because otherwise it will not be send
sock.send((sendStr.encode(encoding)))
userResponse = sock.recv(1024)
#the Responce will be received in byte and will be converted to a string to make it checkable
userResponceStr = userResponse.decode('ascii')
if userResponceStr[:2] == 'OK':
with open(filenameByte, 'rb') as f:
bytesToSend = f.read(1024)
sock.send(bytesToSend)
while bytesToSend != "":
bytesToSend = f.read(1024)
sock.send(bytesToSend)
else:
print("User response not known")
else:
sendStr = "ERR"
sock.send(sendStr.encode(encoding))
sock.close()
def Main():
host = "127.0.0.1"
port = 5000
s = socket.socket()
s.bind((host,port))
s.listen(5)
print("server started.")
while True:
c, addr =s.accept()
print("client connected ip:< " + str(addr) +">")
t = threading.Thread(target = RtrFile, args=("rtrThread",c))
t.start()
s.close()
if __name__ == "__main__":
Main()
processB.py
'''
Created on 29 Nov 2017
#author: Happy student
'''
import socket
from idlelib.IOBinding import encoding
def Main():
host = "127.0.0.1"
port = 5000
s = socket.socket()
s.connect((host,port))
filename = input("Filename? -> ")
if filename != "q":
s.send(filename.encode())
data = s.recv(1024)
dataStr = data.decode('ascii')
if dataStr[:6] == "EXISTS":
filesize = int(dataStr[6:])
message = input("File Exists, " +str(filesize) + "Bytes, download? (Y/N)? ->")
if message == "Y" or message =="y":
sendStr = "OK"
s.send(sendStr.encode(encoding))
#create new file new_filename and
f = open("new_" + filename, "wb")
data = s.recv(1024)
totalRecv = len(data)
f.write(data)
while totalRecv < filesize:
data = s.recv(1024)
totalRecv += len(data)
f.write(data)
print("Download Complete")
else:
print(message +"was not noticed")
exit()
else:
print("File does not exists")#
s.close()
if __name__ == "__main__":
Main()

print contents of file - python socket

I'm trying to print the contents of a file to the client using the defined command 'get'. I am not getting the contents of the file instead the contents are getting over written with Server Says... get test.txt.
Here is my client code:
import socket
import sys
import os
HOST = 'localhost'
PORT = 8082
size = 1024
def ls():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST,PORT))
s.send(userInput)
result = s.recv(size)
print result
s.close()
return
def put(commandName):
socket1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket1.connect((HOST, PORT))
socket1.send(commandName)
string = commandName.split(' ', 1)
inputFile = string[1]
with open(inputFile, 'rb') as file_to_send:
for data in file_to_send:
socket1.sendall(data)
print 'PUT Successful'
socket1.close()
return
def get(commandName):
socket1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket1.connect((HOST, PORT))
socket1.send(commandName)
string = commandName.split(' ', 1)
inputFile = string[1]
with open(inputFile, 'wb') as file_to_write:
while True:
data = socket1.recv(1024)
print data
if not data:
break
print data
file_to_write.write(data)
file_to_write.close()
print 'GET Successful'
#socket1.close()
return
done = False
while not done:
userInput = raw_input()
if "quit" == userInput:
done = True
elif "ls" == userInput:
ls()
else:
string = userInput.split(' ', 1)
if (string[0] == 'put'):
put(userInput)
elif (string[0] == 'get'):
get(userInput)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST,PORT))
s.send(userInput)
data = s.recv(size)
s.close()
print 'Received:', data
And server code:
import socket
import os
import sys
host = ''
port = 8082
backlog = 5
size = 1024
serverID = socket.gethostbyname(socket.gethostname())
info = 'SERVER ID: {} port: {}'.format(serverID, port)
print info
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
done = False
# Loop until client sends 'quit' to server
while not done:
client, address = s.accept()
data = client.recv(size)
print "Server received: ", data
if data:
client.send("Server Says... " + data)
if data == "quit":
done = True
elif data == "ls":
data = os.listdir("C://")
client.send(data[0])
else:
string = data.split(' ', 1)
dataFile = string[1]
if (string[0] == 'put'):
with open(dataFile, 'wb') as file_to_write:
while True:
data = client.recv(1024)
if not data:
break
file_to_write.write(data)
file_to_write.close()
break
print 'Receive Successful'
elif (string[0] == 'get'):
with open(dataFile, 'rb') as file_to_send:
for data in file_to_send:
client.send(data)
print 'Send Successful'
client.close()
s.close()
print "Server exiting."
You are getting the content of the file but it is empty... and your code works just because you probably run it in the same directory.
Your client open file to write (and then it is empty) and the server reads it (both code use the same file name). You probably wanted to read file from C:\ so you should change server code and replace line:
with open(dataFile, 'rb') as file_to_send:
with:
with open('C:\\' + dataFile, 'rb') as file_to_send:
No matter what you send to the server this condition is true so you get "server says..."
if data:
client.send("Server Says... " + data)
You have also several flaws in you client I think. Like your commands are sent 2 times: once in the client 'main' when you do:
s.send(userInput)
And once in the functions like get and ls :
socket1.send(commandName)

Python server proxy - the websites dont reload

I build a server proxy with Python by using socket and select libraries. I got an issue: When the proxy is ready to use and I reload a website it doenst reload it. I get only 3 headers from the server and the client send to the server the variable "data" that contains the client header. If you run the program you'll be able to understand better.
** HostFliter is a function that gets the first line of the header, and returns the domain of the website.
import socket, select
def HostFliter(dataSplit):
dataSplit = dataSplit[0]
print dataSplit," datasplit"
if dataSplit.split(" ")[0] == "GET" or dataSplit.split(" ")[0] == "POST":
dataSplit = dataSplit.split(" ")[1]
dataSplit = dataSplit.replace("http://","")
if dataSplit.find('/') != -1:
dataSplit = dataSplit.split('/')[0]
return dataSplit
else:
return ""
clientSocket = socket.socket()
clientSocket.bind(('0.0.0.0', 80))
clientSocket.listen(100)
open_client_sockets = []
while True:
rlist, wlist, xlist = select.select([clientSocket] + open_client_sockets, open_client_sockets, [])
for currentSocket in rlist:
if currentSocket is clientSocket:
newSocket, addr = clientSocket.accept()
open_client_sockets.append(newSocket)
else:
data = currentSocket.recv(4096)
print data
if data == "":
currentSocket.send("")
currentSocket.close()
open_client_sockets.remove(currentSocket)
print 'Conn is closed'
else:
dataSplit = data.split("\r\n")
Host = HostFliter(dataSplit)
print Host, " Host"
if Host == "":
break
serverSocket = socket.socket()
serverSocket.connect((Host, 80))
serverSocket.send(data)
print "Sent to server"
response = serverSocket.recv(4096)
new_res = ""
while len(new_res) > 0:
new_res = ""
new_res = serverSocket.recv(4096)
response += new_res
currentSocket.send(response)
print "Sent " + Host
Thanks for the helpers!!

Categories

Resources