OSError: [Errno 9] Bad file descriptor - python

I initially tried using python to run but there were different errors so I tried using python3 and received the error in the title. I am trying to connect to server and download a file that has tls implemented.
import socket, ssl, pprint
import os, time
import threading
def main():
s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = ssl.wrap_socket(s2,
server_side = False,
ca_certs="CA.crt",
cert_reqs=ssl.CERT_REQUIRED)
s2.connect(('localhost',10024))
filename = raw_input("What file do you wish to download? -> ")
if filename != 'q':
s2.send(filename)
data = s2.recv(1024)
if data [:7] == 'fEXISTS':
fSize = long(data[7:])
message = raw_input("The file you wish to download is " +str(fSize)+\
"bytes, would you like to proceed? (y/n): ")
if message == 'y':
s2.send ('OK')
f = open('new_'+filename, 'wb')
data = s2.recv(2000000)
totalRecv = len(data)
f.write(data)
while totalRecv < fSize:
data = s2.recv(2000000)
totalRecv += len(data)
f.write(data)
progress = ((totalRecv/float(fSize))*100)
print ("{0: .2F}".format(progress)+\
"% Completed")
else:
print ("ERROR: File does not exist!")
s2.close()
if __name__ == '__main__':
main()

After wrapping the socket in an SSL context (with ssl.wrap_socket), you should not be using the original socket anymore.
You should be calling connect, send, recv, etc. on ssl_sock, not on s2.
(Specifically, when you call ssl.wrap_socket, the .detach method is called on the original socket which removes the file descriptor from it. The file descriptor is transferred to the SSL socket instance. The only thing you can do with the original then is close/destroy it.)

Related

Python Socket file transfer without closing sockets [duplicate]

This question already has answers here:
sending multiple files in python
(1 answer)
download multiple subsequent files from one server with one TCP handshake
(1 answer)
Sending multiple images with socket
(1 answer)
Sending multiple files through a TCP socket
(2 answers)
Closed last year.
I've been trying to transfer large files through python sockets, I can do it but it only works well if I close the connection, I want to keep the connection open and keep transfering files after that
Server:
import socket
import sys
from tqdm import tqdm
IP =
PORT =
ADDR = (IP, PORT)
SIZE = 4096
FORMAT = "utf-8"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(ADDR)
server.listen()
print("[+] Listening...")
conn, addr = server.accept()
print(f"[+] Client connected from {addr[0]}:{addr[1]}")
#last try:
def receiver():
file_name = conn.recv(1024).decode()
file_size = conn.recv(1024).decode()
with open(file_name, "wb") as file:
c = 0
while c <= int(file_size):
data = conn.recv(1024)
if not (data):
break
file.write(data)
c += len(data)
def execute_rem(command):
conn.send(command.encode(FORMAT))
if command[0] == "exit":
conn.close()
server.close()
exit()
def run():
while True:
command = input(">> ")
if len(command) != 0:
conn.send(command.encode(FORMAT))
command = command.split(" ")
if command[0] == "download" and len(command) == 2:
receiver()
else:
result = conn.recv(SIZE)
if result == "1":
continue
else:
print(str(result, FORMAT))
run()
client:
import os
import sys
import socket
import time
import subprocess
from tqdm import tqdm
IP =
PORT =
ADDR = (IP, PORT)
SIZE = 4096
FORMAT = "utf-8"
WAITTIME = 10
client = 0
while True:
try:
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(ADDR)
break
except socket.error:
time.sleep(WAITTIME)
def exec_comnd(command):
cmd = subprocess.Popen(command,shell = True, stderr = subprocess.PIPE, stdout = subprocess.PIPE, stdin = subprocess.PIPE)
byte = cmd.stdout.read()+cmd.stderr.read()
if len(byte) == 0:
byte = "1"
return byte
def f_send(file_name):
file_size = os.path.getsize(file_name)
client.send(file_name.encode())
client.send(str(file_size).encode())
with open(file_name, "rb") as file:
c = 0
while c <= file_size:
data = file.read(1024)
if not (data):
break
client.sendall(data)
c += len(data)
def run():
while True:
command = client.recv(SIZE).decode(FORMAT)
command = command.split(" ")
if command[0] == "exit":
client.close()
exit()
elif command[0] == "cd" and len(command) == 2:
path = command[1]
os.chdir(path)
client.send(("Cambio a directorio " + path).encode(FORMAT))
elif command[0] == "download" and len(command) == 2:
f_send(command[1])
else:
res_comnd = exec_comnd(command)
client.send(res_comnd)
run()
This is my last attempt but I have tried different ways. The file gets sent but the server gets stuck until I ctl+c, after that, based on the output, server gets stuck on "data = conn.recv(1024))" (terminal output stops at "download test.jpg") and client gets stuck on "client.send(res_comnd)". I don't see why, is the only way closing the socket after the file transfer?
server output:
[+] Listening... [+] Client connected from
IP:PORT
>> download test.jpg
^CTraceback (most recent call last): File "/home/xxxx/project/nuev/server.py", line 94, in <module>
run() File "/home/xxxx/project/nuev/server.py", line 84, in run
receiver() File "/home/xxxx/project/nuev/server.py", line 36, in receiver
data = conn.recv(1024) KeyboardInterrupt
client output:
Traceback (most recent call last): File "C:\Users\xxxx\Desktop\client.py", line 108, in <module>
run() File "C:\Users\xxxx\Desktop\client.py", line 105, in run
client.send(res_comnd) ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine

How to transfer more files rather than just one using python?

I made a file transferrer and the problem is that out of unknown reason it lets me only send one file... When I try the second time the program works fine, but the file doesn't show up in directory. It would mean a lot to me if someone helped me out.
Code for sender:
import os
import shutil
import socket
import time
# Creating a socket.
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((socket.gethostname(), 22222))
sock.listen(5)
print("Host Name: ", sock.getsockname())
# Accepting the connection.
client, addr = sock.accept()
original = ""
print("When you want to stop with file uploading type -> STOP <-")
while (1):
original = input(str("Filepath:"))
if (original!="STOP"):
filename = os.path.basename(original)
target = r'C:\Users\Gasper\Desktop\transfer\filename'
path = target.replace('filename', filename)
new_file = shutil.copy(original, path)
# Getting file details.
file_name = filename
file_size = os.path.getsize(file_name)
# Sending file_name and detail.
client.send(file_name.encode())
client.send(str(file_size).encode())
# Opening file and sending data.
with open(file_name, "rb") as file:
c = 0
# Running loop while c != file_size.
while c <= file_size:
data = file.read(1024)
if not data:
break
client.sendall(data)
c += len(data)
os.remove(filename)
else:
break
print("File Transfer Complete!")
input("Press enter to exit...")
# Closing the socket.
sock.close()
Code for receiver:
import socket
import time
host = input("Host Name: ")
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Trying to connect to socket.
try:
sock.connect((host, 22222))
print("Connected Successfully")
except:
print("Unable to connect")
exit(0)
# Send file details.
file_name = sock.recv(100).decode()
file_size = sock.recv(100).decode()
# Opening and reading file.
with open("./rec/" + file_name, "wb") as file:
c = 0
# Starting the time capture.
start_time = time.time()
# Running the loop while file is recieved.
while c <= int(file_size):
data = sock.recv(1024)
if not data:
break
file.write(data)
c += len(data)
# Ending the time capture.
end_time = time.time()
print("File transfer Complete!")
input("Press enter to exit...")
# Closing the socket.
sock.close()
Example:
Filepath: C\Users\Admin\Desktop\Directory\File1.txt(I put in the first file path and it transfers successfully)
Filepath: C\Users\Admin\Desktop\Directory\File2.txt(I put in the second file path and it doesnt transfer at all)

Napster-style peer-to-peer (P2P) file sharing system using rpyc and message-orianted(Python)

I have a task in which I should make Napster-style peer-to-peer (P2P) file sharing system. I used rpyc and message-oriented at the same time, but I have a problem when I download a file from other peer - the code just runs infinite and never stops, no output.
Peer has two classes Client and server
from socket import *
import socket
import os
import pickle
import rpyc
from rpyc.utils.server import ThreadedServer
from const import *
class Client():
conn = rpyc.connect(HOST, PORT) # Connect to the index_server
def lookUp(self,filename):
PeerList = self.conn.root.exposed_search(filename)
if PeerList==False:
print "no File with this Name"
else:
print PeerList
def register_on_server(self,Filename,port):
self.conn.root.exposed_register(Filename,port)
def download(self, serverhost, serverport, filename): # function download a file from another peer
sock.connect((serverhost,serverport))
print("Client Connected to download a file")
sock.send(pickle.dumps(filename))
localpath = "C:\Users\aa\PycharmProjects\task1\downloadfiles"
data = sock.recv(1024)
totalRecv = len(data)
f = open(localpath + '/' + filename, 'wb')
f.write(data)
filesize = os.path.getsize('C:\Users\aa\PycharmProjects\task1\uploadfiles' + '/' + filename)
while totalRecv < filesize:
data = sock.recv(1024)
totalRecv += len(data)
f.write(data)
print("File is downloaded Successfully")
sock.close()
class Server(rpyc.Service):
def __init__(self, host, port):
self.host = host
self.port = port # the port it will listen to
global sock
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # socket for incoming calls
sock.bind((self.host, self.port)) # bind socket to an address
sock.listen(5) # max num connections
def obtain(self):
remotepath = "C:\Users\aa\PycharmProjects\task1\uploadfiles"
while True:
client, address = sock.accept()
print("Client Connected to download a file")
try:
filename = client.recv(1024)
if os.path.exists(remotepath + '/' + filename):
filesize = os.path.getsize(remotepath + '/' + filename)
if filesize > 0:
client.send(str(filesize))
with open(remotepath + '/' + filename, 'rb') as f:
bytes = f.read(1024)
client.send(bytes)
while bytes != "":
bytes = f.read(1024)
client.send(bytes)
else:
client.send("Empty")
else:
client.send("False")
except:
client.close()
return False
if __name__ == "__Server__":
server = ThreadedServer(Server, hostname=Server.host, port=Server.port)
server.start()
{Peer2}
from time import sleep
import rpyc
from peer import *
from const import *
peer2 = Client()
print ('1-register')
print ('2-search')
print ('3-download')
while(True):
commend = raw_input("enter your commend")
if commend == 'register':
filename = raw_input("write the file name")
peer2.register_on_server(filename,PeeR2PORT)
elif commend == 'search':
filename = raw_input("write the file name")
peer2.lookUp(filename)
elif commend == 'download':
port = raw_input("enter the other peer port")
host = raw_input("enter the other peer host")
filename = raw_input("enter the file name")
peer1 = Server(PeeR1HOST, PeeR1PORT)
peer1.obtain()
peer2.download(host, port, filename)
You create a call to peer1.obtain() which runs the peer to accept calls from different peers to download the file. However, you try to call peer1.download() from the same peer while it is already listening for incoming calls. You need to separate peer1.download() to run from different peer.
You need to revise how Napster FileSharing System works.
We are not here to solve your assignment. You seem to have good knowledge with python, the issue is that you do not understand the task good enough. We can help you with understanding its concept, helping you with syntax errors,..,etc.

How to finish a socket file transfer in Python?

I have a Client and a Server and I need to transfer some files using sockets. I can send small messages, but when I try to send a File, the problems begins...
client.py:
from socket import *
from threading import Thread
import sys
import hashlib
class Client(object):
ASK_LIST_FILES = "#001" # 001 is the requisition code to list
# all the files
ASK_SPECIFIC_FILE = "#002" # 002 is the requisition code to a
# specific file
SEND_FILE = "#003" # 003 is the requisition code to send one
# file
AUTHENTICATION = "#004" # 004 is the requisition code to user
# authentication
listOfFiles = []
def __init__(self):
try:
self.clientSocket = socket(AF_INET, SOCK_STREAM)
except (error):
print("Failed to create a Socket.")
sys.exit()
def connect(self, addr):
try:
self.clientSocket.connect(addr)
except (error):
print("Failed to connect.")
sys.exit()
print(self.clientSocket.recv(1024).decode())
def closeConnection(self):
self.clientSocket.close()
def _askFileList(self):
try:
data = Client.ASK_LIST_FILES
self.clientSocket.sendall(data.encode())
# self._recvFileList()
except (error):
print("Failed asking for the list of files.")
self.closeConnection()
sys.exit()
thread = Thread(target = self._recvFileList)
thread.start()
def _recvFileList(self):
print("Waiting for the list...")
self.listOfFiles = []
while len(self.listOfFiles) == 0:
data = self.clientSocket.recv(1024).decode()
if (data):
self.listOfFiles = data.split(',')
if(len(self.listOfFiles) > 0):
print (self.listOfFiles)
def _askForFile(self, fileIndex):
fileIndex = fileIndex - 1
try:
data = Client.ASK_SPECIFIC_FILE + "#" + str(fileIndex)
self.clientSocket.sendall(data.encode())
except(error):
print("Failed to ask for an specific file.")
self.closeConnection()
sys.exit()
self._downloadFile(fileIndex)
def _downloadFile(self, fileIndex):
print("Starting receiving file")
f = open("_" + self.listOfFiles[fileIndex], "wb+")
read = self.clientSocket.recv(1024)
# print(read)
# f.close
while len(read) > 0:
print(read)
f.write(read)
f.flush()
read = self.clientSocket.recv(1024)
f.flush()
f.close()
self.closeConnection()
server.py
from socket import *
from threading import Thread
import sys
import glob
class Server(object):
def __init__(self):
try:
self.serverSocket = socket(AF_INET, SOCK_STREAM)
except (error):
print("Failed to create a Socket.")
sys.exit()
def connect(self, addr):
try:
self.serverSocket.bind(addr)
except (error):
print ("Failed on binding.")
sys.exit()
def closeConnection(self):
self.serverSocket.close()
def waitClients(self, num):
while True:
print("Waiting for clients...")
self.serverSocket.listen(num)
conn, addr = self.serverSocket.accept()
print("New client found...")
thread = Thread(target = self.clientThread, args = (conn,))
thread.start()
def clientThread(self, conn):
WELCOME_MSG = "Welcome to the server"
conn.send(WELCOME_MSG.encode())
while True:
data = conn.recv(2024).decode()
if(data):
# print(data)
# reply = 'OK: ' + data
# conn.sendall(reply.encode())
if(data == "#001"):
listOfFiles = self.getFileList()
strListOfFiles = ','.join(listOfFiles)
self._sendFileList(strListOfFiles, conn)
else:
dataCode = data.split('#')
print(dataCode)
if(dataCode[1] == "002"):
print("Asking for file")
self._sendFile(int(dataCode[2]), conn)
if(dataCode[1] == "003"):
print("Pedido de login")
if self._authentication(dataCode[2]):
conn.send("OK".encode())
# self._recvFile(conn)
else:
conn.send("FAILED".encode())
def _sendFile(self, fileIndex, conn):
listOfFiles = self.getFileList()
print(fileIndex)
print(listOfFiles[fileIndex])
f = open(listOfFiles[fileIndex], "rb")
read = f.read(1024)
while len(read) > 0:
conn.send(read)
read = f.read(1024)
f.close()
def _sendFileList(self, strList, conn):
try:
conn.sendall(strList.encode())
except (error):
print("Failed to send list of files.")
def getFileList(self):
return glob.glob("files/*")
When I try to get a file from my server, I can transfer everything but the connection never ends. What is going on with my code?
First, you are doing here the most common error using TCP: assume all data sent in a single send() will be got identically in a single recv(). This is untrue for TCP, because it is an octet stream, not a message stream. Your code will work only under ideal (lab) conditions and could mysteriously fail in a real world usage. You should either explicitly invent message boundaries in TCP streams, or switch e.g. to SCTP. The latter is available now almost everywhere and keeps message boundaries across a network connection.
The second your error is directly connected to the first one. When sending file, you don't provide any explicit mark that file has been finished. So, clients waits forever. You might try to close server connection to show that file is finished, but in that case client won't be able to distinguish real file end and connection loss; moreover, the connection won't be reusable for further commands. You would select one of the following ways:
Prefix a file contents with its length. In this case, client will know how many bytes shall be received for the file.
Send file contents as a chunk sequence, prefixing each chunk with its length (only for TCP) and with mark whether this chunk is last (for both transports). Alternatively, a special mark "EOF" can be sent without data.
Similarly, control messages and their responses shall be provided with either length prefix or a terminator which can't appear inside such message.
When you finish developing this, you would look at FTP and HTTP; both addresses all issues I described here but in principally different ways.

Python - AttributeError: 'tuple' object has no attribute 'read'

I am working on a simple python client and server that can write code to a file as its sent. So far I have been stuck on this error: AttributeError: 'tuple' object has no attribute 'read'
Here is the client's code:
# CCSP Client
# (C) Chris Dorman - 2013 - GPLv2
import socket
import sys
# Some settings
host = raw_input('Enter the Host: ')
port = 7700
buff = 24
connectionmax = 10
# Connect to server
server = socket.socket()
server.connect((host, port))
print 'Connected!'
while True:
open_file = raw_input("File (include path): ")
fcode = open(open_file, "rb")
while True:
readcode = fcode.read(buff)
server.send(readcode)
if not fcode:
server.send("OK\n")
print "Transfer complete"
break
Server:
# CCSP Server
# (C) Chris Dorman - 2013 - GPLv2
import socket
import sys
import string
import random
def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
return ''.join(random.choice(chars) for x in range(size))
host = "0.0.0.0"
port = 7700
buff = 1024
filepath = "/home/chris/"
extension = ".txt"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((host, port))
print "Server Started"
while True:
server.listen(1)
conn = server.accept()
print 'Client' + str(conn)
print 'Generating a random file'
filename = filepath + str(id_generator()) + extension
fcode = open(filename, "wb")
while True:
if conn != 0:
code = conn.read(buff)
fcode.write(buff)
if conn == "DONE":
print 'Transfer complete'
break #EOT
Any help with getting this to work would be awesome. I just keep getting that dumb error when it gets down to: code = conn.read(buff) on the servers script
You should read some doc. accept() returns a tuple not a file-like object.
As others have pointed out, accept() returns a tuple. It looks like you want the first item in the tuple, which will be a new socket object.
Of course, sockets don't have a read() method either. I'm guessing that what you actually want is:
code = conn.recv(buff)
As recv() returns data that has been written to a socket's connection.

Categories