client-server python and file opening error - python

I am starting in python and developing a client / server script with some input parameters in terminal,arguments:(in) (out) (ip) (port) (mode) according to the code below.In passive mode, it functions as a server, in active mode it functions as a client. But I do not understand the reason for the errors presented. Can someone explain to me what's going on? Thanks.
code
def Main():
mode = sys.argv[5]
i = 0 # Auxiliar variable in loop
if (mode == "passive"):
port = int(sys.argv[4])
mySocket = socket.socket()
mySocket.bind(('', port)) # Passive connection, for server
mySocket.listen(1)
conn, addr = mySocket.accept()
conn.settimeout(1) # Timeout = 1 segundo
conn.setblocking(0) # Non blockable mode
print("Connection from: " + str(addr))
print("Connected as server")
in_arq = open(sys.argv[1], 'r')
message = in_arq.read() # File to be send
out_arq = open(sys.argv[2], 'w') # File to save data received
elif (mode == "ative"):
host = sys.argv[3]
port = int(sys.argv[4])
mySocket = socket.socket()
mySocket.connect((host, port)) # Active connection, for client
mySocket.settimeout(1) # Timeout = 1 segundo
mySocket.setblocking(0) # Non blockable mode
print("Connected as client")
in_arq = open(sys.argv[1], 'r')
message = in_arq.read() # File to be send
out_arq = open(sys.argv[2], 'w') # File to save data received
else:
print("Wrong arguments.")
if __name__ == '__main__':
Main()
errors:
C:\Users\AppData\Local\Programs\Python\Python35-32\python.exe C:/Users/Desktop/emulator.py C:\Users\Desktop\textinput C:\Users\Desktop\textoutput 127.0.0.1 54000 ative
Traceback (most recent call last):
File "C:/Users/Desktop/emulator.py", line 221, in <module>
Main()
File "C:/Users/Desktop/emulator.py", line 202, in Main
in_arq = open(sys.argv[1], 'r')
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\Desktop\\textinput'
Connected as client

Related

Python UDP File Transfer

I'm creating a udp file transfer using python with a client (requests file from server), a server (receives request from client and passes it to the relevant worker) and worker1/worker2 (recieve request from server, if file exists, sends to server to pass back to client) and its all ran in docker containers with an ubuntu image*
Currently, when I type the name of the file I want in the client container, nothing works. I think the file name isn't actually being sent to the server but I can't figure out why at all. I was wondering if anyone can spot my mistake?
Server:
from fileinput import filename
import socket
import time
localIP = "127.0.0.1"
localPort = 50001
bufSize = 1024
msg = "Server is connecting..."
print(msg)
workerAddressPorts = [('127.0.0.1', 50002), ('127.0.0.1', 50003)]
# Create datagram sockets and bind to address and ip
UDPServerSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
UDPServerSocket.bind((localIP, localPort))
print("Server is waiting for packet...")
while True:
bytesAddressPair = UDPServerSocket.recvfrom(bufSize)
clientBuf = bytesAddressPair[0]
clientAddr = bytesAddressPair[1]
msgFrom = 'Message from Client:{}'.format(clientBuf.decode('utf-8'))
print(msgFrom)
for workerAddressPort in workerAddressPorts:
UDPServerSocket.sendto(clientBuf, workerAddressPort) # send file name to worker
print(f'Clients request has been sent to Worker {workerAddressPort[0]}')
workerBuf = UDPServerSocket.recvfrom(bufSize)[0] # saving data from worker
print(f'Request recieved.')
UDPServerSocket.sendto(workerBuf, clientAddr) # sending data to client
print('Packet from Worker has been sent to Client')
while not workerBuf: # split file to prevent buffer overflow
workerBuf = UDPServerSocket.recvfrom(bufSize)[0]
print(f'Packet received.')
UDPServerSocket.sendto(workerBuf, clientAddr)
print('Packet from worker has been sent to Client')
print('File has been sent to Client.')
Client:
import sys
msgFrom = input('Name of file: ')
print(msgFrom)
bytesToSend = str.encode(msgFrom, 'utf-8')
serverAddressPort = ("127.0.0.1", 50001)
bufSize = 1024
# create UDP Client Socket and send to server
UDPClientSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
UDPClientSocket.sendto(bytesToSend, serverAddressPort)
while (True):
try:
serverBuf = UDPClientSocket.recvfrom(bufSize)[0]
if len(serverBuf) > 0:
print('Packet incoming...')
msg = serverBuf.decode('utf-8')
if msg == 'NO_FILE':
print('No such file exists.')
break
elif msg == 'END_OF_FILE':
print('Empty file.')
break
else:
f = open(msgFrom, 'wb')
f.write(serverBuf)
f.close()
except Exception as e:
print(e)
Worker:
import socket
import time
from os.path import exists
bufSize = 1024
msg = "Worker is connecting..."
print(msg)
serverAddressPort = ("127.0.0.1", 50001)
# Create a datagram socket and bind to address and ip
UDPWorkerSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
UDPWorkerSocket.bind(('127.0.0.1', 50002))
print("Worker is connected and waiting...")
while True:
time.sleep(1)
bytesAddressPair = UDPWorkerSocket.recvfrom(bufSize)
msg = bytesAddressPair[0]
addr = bytesAddressPair[1]
print('Packet Incoming...')
file_name = msg.decode('utf-8')
script_dir = os.path.dirname("C:/Users/Vic/Documents/3rd Year TCD/CSU33031 Computer Networks/Assignments/Assignment1.3/Files to send")
abs_file_path = os.path.join(script_dir, file_name)
if exists(file_name):
f = open(file_name, 'rb')
data = f.read(bufSize)
while data:
if UDPWorkerSocket.sendto(data, serverAddressPort):
data = f.read(bufSize)
time.sleep(1)
print('Sent to Server.')
else:
UDPWorkerSocket.sendto(str.encode('NO_FILE'), serverAddressPort)
print(f'{file_name} was not found. Moving to next available worker..')
Hoping that the for statement in the server, iterates the two worker files(only included one) so if it can't find the file in one worker it moves to the other
*the client is connected to a different network as the two workers. The server is connected to both networks
Thanks in advance!!

Send big file over socket

I have a video file and want to send it over socket. Video is send to the client but video is not playable and also video size received is 2 KB. And acutely video size is 43 MB. What is the problem?
Server:
import socket
try:
soc = socket.socket()
print('socked created.')
host = ''
port = 8080
soc.bind((host, port))
print('soc bound.')
soc.listen(10)
print('waiting for connecting...')
con, addr = soc.accept()
print('server connected to IP: ' + addr[0] + " port: " + str(addr[1]))
while True:
filename = input('enter filename: ')
file = open(filename, 'rb')
sendfile = file.read(9000000)
con.send(sendfile)
print("file has been send.")
break
con.close()
soc.close()
except socket.error as err:
print('error ', str(err))
client:
import socket
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('socked created. waiting for connecting to server...')
server_address = ("192.168.1.3", 8080)
soc.connect(server_address)
print('connected to the server.')
while True:
recvfile = soc.recv(9000000)
savefilebyname = input("enter file name: ")
openfile = open(savefilebyname, 'wb')
openfile.write(recvfile)
openfile.close()
break
print("File has been received.")
soc.close()
Check the return value of send and recv. The 9000000 value is a maximum but not guaranteed value to send/recv. Alternatively, use sendall.
For recv, you have to loop until you receive all the data. If you close the socket after the file is sent, recv will return zero when all the data is received.
FYI, your while True: in both files never loops due to the break, so they are unnecessary.
Here's something that should work...
server.py
import socket
soc = socket.socket()
soc.bind(('',8080))
soc.listen(1)
print('waiting for connection...')
with soc:
con,addr = soc.accept()
print('server connected to',addr)
with con:
filename = input('enter filename to send: ')
with open(filename, 'rb') as file:
sendfile = file.read()
con.sendall(sendfile)
print('file sent')
client.py
import socket
soc = socket.socket()
soc.connect(('localhost',8080))
savefilename = input("enter file name to receive: ")
with soc,open(savefilename,'wb') as file:
while True:
recvfile = soc.recv(4096)
if not recvfile: break
file.write(recvfile)
print("File has been received.")

Python File Server Only Works with One Thread Running

I have made a file server on python using sockets and threads. The program is supposed to allow the client to upload and download files from the server.
The program works perfectly when only one thread is running, but when both threads are running the server gives an error when trying to upload a file, and when trying to download the program just stops doing anything after the client enters 'Y' to initiate the download.
Here is the code for the client:
import socket
import os
def DownloadFile(s, host, port):
s.connect((host, port))
s.send(str.encode('DNLD'))
filename = input('Filename? ->')
if filename != 'q':
s.send(str.encode(filename))
data = s.recv(2048).decode('UTF-8')
if data[:6] == 'EXISTS':
filesize = data[6:]
message = input('File Exists, ' + str(filesize) + ' Bytes. Download? (Y/N) ->')
if message == 'Y' or message == 'y':
s.send(str.encode('OK'))
f = open('copy of '+filename, 'wb')
data = s.recv(2048)
totalRecv = len(data)
f.write(data)
while totalRecv < int(filesize):
data = s.recv(2048)
totalRecv += len(data)
f.write(data)
print('{}'.format(round((totalRecv/float(filesize))*100),2)+'% Complete')
print('Download Complete!')
s.close()
else:
print('File does not exist')
s.close()
Main()
def UploadFile(s, host, port):
s.connect((host, port))
s.send(str.encode('UPLD'))
filename = input('Filename? ->')
if os.path.isfile(filename):
filesize = os.path.getsize(filename)
filesize = str(filesize)
s.send(str.encode('EXISTS ' + filename))
s.send(str.encode(filesize))
ready = input('Ready to upload. Proceed? (Y/N) ->')
if ready == 'Y' or ready == 'y':
s.send(str.encode('OK'))
with open(filename, 'rb') as f:
bytesToSend = f.read(2048)
s.send(bytesToSend)
while bytesToSend != '':
bytesToSend = f.read(2048)
s.send(bytesToSend)
s.close()
else:
print('File does not exist.')
s.close()
Main()
def Main():
host = '127.0.0.1'
port = 10000
s = socket.socket()
while True:
choice = int(input('Please enter your choice:\n\n1. Upload a file to the server.\n2. Download a file from the server\n3. Quit.\n\n->'))
if choice == 1:
UploadFile(s, host, port)
break
elif choice == 2:
DownloadFile(s, host, port)
break
elif choice == 3:
s.close()
break
else:
print('Please enter a valid choice.')
if __name__ == '__main__':
Main()
And here is the code for the server:
import socket
import threading
import os
def SendFile(name, s):
check = s.recv(2048).decode('UTF-8')
if check == 'DNLD':
filename = s.recv(2048)
if os.path.isfile(filename):
send = os.path.getsize(filename)
send = str(send)
s.send(str.encode('EXISTS ' + send))
userResponse = s.recv(2048)
userResponse = userResponse.decode('UTF-8')
if userResponse[:2] == 'OK':
with open(filename, 'rb') as f:
bytesToSend = f.read(2048)
s.send(bytesToSend)
while bytesToSend != '':
bytesToSend = f.read(2048)
s.send(bytesToSend)
else:
s.send(str.encode('ERR'))
s.close()
def ReceiveFile(name, s):
check = s.recv(2048).decode('UTF-8')
if check == 'UPLD':
data = s.recv(2048).decode('UTF-8')
if data[:6] == 'EXISTS':
filename = data[6:]
data = s.recv(2048).decode('UTF-8')
filesize = data
userResponse = s.recv(2048)
userResponse = userResponse.decode('UTF-8')
if userResponse[:2] == 'OK':
f = open('copy of '+filename, 'wb')
data = s.recv(2048)
totalRecv = len(data)
f.write(data)
while totalRecv < int(filesize):
data = s.recv(2048)
totalRecv += len(data)
f.write(data)
print('Download Complete!')
def Main():
host = '127.0.0.1'
port = 10000
s = socket.socket()
s.bind((host, port))
s.listen(5)
print('Server Started')
while True:
c, addr = s.accept()
print('Client Connected: ' + str(addr))
Send = threading.Thread(target=SendFile, args=('sendThread', c))
Send.start()
Receive = threading.Thread(target=ReceiveFile, args=('retrThread', c))
Receive.start()
s.close()
if __name__ == '__main__':
Main()
If I were to comment out Send.start() or Receive.start() then whatever thread isn't commented out would work perfectly.
Here is the error given in the server when trying to upload a file with both threads running:
Exception in thread Thread-2:
Traceback (most recent call last):
File "C:\Python34\lib\threading.py", line 920, in _bootstrap_inner
self.run()
File "C:\Python34\lib\threading.py", line 868, in run
self._target(*self._args, **self._kwargs)
File "(file location)", line 28, in ReceiveFile
check = s.recv(2048).decode('UTF-8')
OSError: [WinError 10038] An operation was attempted on something that is not a socket
And here is the output in the client when trying to download a file when both threads are running:
Please enter your choice:
1. Upload a file to the server.
2. Download a file from the server
3. Quit.
->2
Filename? ->cat.jpg
File Exists, 10634 Bytes. Download? (Y/N) ->Y
Nothing else happens after entering Y.
If anyone knows what is going wrong I would really appreciate some help.
That's not the way io and threads work. You have here 2 threads competing from the same input data. One will get first packet be it for it or not, and it is likely that one of the following packet will be eaten by the other thread => the first one will never see it!
You can delegate the processing of a conversation to a thread but to a single one that will call a send or receive function once it will have identified the request.
That is not all. TCP is a stream protocol. Packets can be splitted or re-assembled by any piece along the connection (sender, receiver and any gateway). So you should use delimiters to tell the peer that a name or a command if complete. And good practices recommend to pass the size when sending binary data, here again for the peer to know when the data is complete.
Good luck in your journey is the socket world ;-)

socket.gaierror: Errno 11004 getaddrinfo failed

i am trying to create a proxy server script with python when i run it i have this arror messages please can i know what are the mistakes i've done and how to avoid them (i sow the script on a site)
how the script looks like !
import socket
from thread import *
import sys
host = ""
port = 91
def start():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(5)
print "[+] listening ..."
while True:
try:
connection, address = s.accept()
data = connection.recv(1024)
start_new_thread(conn_string, (data, connection))
except KeyboardInterrupt:
print "\n\nclosing !"
def conn_string(data, con):
webserver = ""
portserver = 0
f_li = data.split('\n')[0]
lien = f_li.split(' ')[1]
http_pos = lien.find("://")
if http_pos == -1:
url = lien
else:
url = lien[(http_pos+3):]
port_pos = url.find(':')
if port_pos == -1:
portserver = 80
else:
portserver = url[(port_pos+1):]
s_pos = url.find('/')
if s_pos == -1:
webserver = url
else:
webserver = url[:(s_pos)]
proxy_server(webserver, portserver, data, con)
def proxy_server(webserver, portserver, data, con):
print webserver
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((webserver, int(portserver)))
s.send(data)
while True:
red = s.recv(8192)
if len(red) > 0:
con.send(red)
start()
this is one of the error messages that i have !
Unhandled exception in thread started by <function conn_string at 0x0248CEF0>
Traceback (most recent call last):
File "C:\Users\none2\Desktop\Nouveau dossier\Target.py", line 52, in conn_stri
ng
proxy_server(webserver, portserver, data, con)
File "C:\Users\none2\Desktop\Nouveau dossier\Target.py", line 57, in proxy_ser
ver
s.connect((webserver, int(portserver)))
File "C:\Python27\lib\socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
socket.gaierror: [Errno 11004] getaddrinfo failed
can you replace
start_new_thread(conn_string, (data, connection))
line with
start_new_thread(conn_string(data, connection))
tried running the same file, it seems above one is the only error

python errno 23 - socket livestatus

I'm trying to send two queries to the server with this script, to get the MK Livestatus:
live.py
#!/usr/bin/python
socket_path = "/tmp/run/live"
import socket
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(socket_path)
# Get Hosts
hosts = s.send("GET hosts\nColumns: name\n")
s.shutdown(socket.SHUT_WR)
hosts = s.recv(1024)
hosts = [ line.split(';') for line in hosts.split('\n')[:-1] ]
hostsB = s.send("GET hosts\nColumns: name\n")
s.close()
But I get this error:
Traceback (most recent call last): File "live.py", line 13, in
hostsB = s.send("GET hosts\nColumns: name\n") socket.error:
[Errno 32] Broken pipe
I think the error is related to the command "s.shutdown(socket.SHUT_WR)". But the author says, that this is required. You will get no answer (timeout?), if you remove this line.
How can I send two queries?
SOLUTION
so ... I've written a function that does the job :-)
Function
def sendQuery(query):
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(socket_path)
s.send(query)
s.shutdown(socket.SHUT_WR)
answer = ''
while True:
data = s.recv(1024)
answer += data
if len(data) < 1024:
break
s.close()
return answer
Usage
sendQuery("GET hosts\nColumns: name\n")
so ... I've written a function that does the job :-)
Function
def sendQuery(query):
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(socket_path)
s.send(query)
s.shutdown(socket.SHUT_WR)
answer = ''
while True:
data = s.recv(1024)
answer += data
if len(data) < 1024:
break
s.close()
return answer
Usage
sendQuery("GET hosts\nColumns: name\n")

Categories

Resources