I am trying this scenario:
Client sends file to server
Server updates on file and save it
Sends updated file back to client
Steps 1 and 2 are done correctly as I wanted but when client finishes sending the socket closes. I've tried this code but its not working. Any suggestions?
Client:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
H = socket.gethostname()
P = 1111
s.connect((H,P))
with open('File.txt', 'rb') as fileName:
for data in fileName:
s.sendall(data)
with open('ReFile.txt', 'wb') as File:
while True:
data = s.recv(1024)
print data
if not data:
break
File.write(data)
File.close()
Server:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
H= socket.gethostname()
P = 1111
s.bind((H, P))
s.listen(6)
c, address = s.accept()
print 'Connection with ' , address
with open('ReFile.txt', 'wb') as RecFile:
while True:
data = c.recv(1024)
print data
if not data:
break
RecFile.write(data)
RecFile.write("updated version")
RecFile.close()
with open('ReFile.txt', 'rb') as file:
for data in file:
s.sendall(data)
s.close()
Try this:
Server:
import socket
s = socket.socket()
H = socket.gethostname()
P = 1111
s.bind((H, P))
s.listen(6)
c, address = s.accept()
print 'Connection with ', address
lenF = int(c.recv(1024))
if lenF != 0:
c.sendall('Send data')
data = c.recv(lenF)
data += "\nUpdated Version"
RecFile = open('ReFile.txt','w')
RecFile.write(str(data))
RecFile.close()
fileN = open('ReFile.txt')
data = fileN.read(-1)
fileN.close()
lenF = len(data)
c.send(str(lenF))
if c.recv(5) == 'Ready':
c.send(data)
Here I am using lenF variable to get the size of file that I am getting from the client.
Client:
import socket
s = socket.socket()
H = socket.gethostname()
P = 1111
s.connect((H,P))
fileName = open('file.txt')
data = fileName.read(-1)
fileName.close()
dataL = int(len(data))
s.send(str(dataL))
validCheck = s.recv(9)
if validCheck == 'Send data':
print 'Sending file.......'
s.send(data)
dataL = int(s.recv(1024))
if dataL != 0:
s.send('Ready')
data = s.recv(dataL)
File = open('ReFile.txt','w')
File.write(data)
File.close()
Here I am using dataL variable to receive data length(file) and sending it.
Related
I want to send images and text for the server from the client file. But since I'm new to the socket, I don't know how to do it. Please help me.
codes:
#server.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("localhost", 1236))
s.listen(5)
c, addr = s.accept()
image_datas, d1, d2 = c.recv(1024)
f = open("C:\\Users\\SD\\Desktop\\image.jpg", "wb")
while image_datas:
f.write(image_datas)
image_datas = c.recv(1024)
print(d1,d2)
f.close()
c.close()
s.close()
#client.py
import socket
c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
c.connect(("tcp.ngrok.io", ))
f = open("image.jpg", "rb")
img_data = f.read()
data1 = "hello"
data2 = "server"
c.send(img_data,data2,data3)
f.close()
c.close()
i am trying to make a server and client which sends a file from client to server and the server saves it to hard then the server asks for another file and if the answer of client is yes then the client sends the second file then the server again saves it and if the client answer is no server close the socket when i run this code the first file is sent
and received successfully but after that both of the server and the client freeze and nothing happens what is wrong with it and how can i fix it?
my server code:
import socket
host = 'localhost'
port = 4444
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(5)
(client, (ip, port))=s.accept()
while True:
data = "".join(iter(lambda: client.recv(1), "\n"))
with open('filehere.txt', 'w') as file:
for item in data:
file.write("%s" % item)
if not data: break
client.send("is there any other file?")
d = client.recv(2048)
if d == "yes":
while True:
data = "".join(iter(lambda: client.recv(1), "\n")
with open('filehere1.txt', 'w') as file:
for item in data:
file.write("%s" % item)
if not data: break
s.close()
else:
s.close()
my client code:
import socket
host = 'locahost'
port = 4444
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
f = open('myfile.txt', 'rb')
l = f.read()
while True:
for line in l:
s.send(line)
break
f.close()
d = s.recv(2048)
a = raw_input(d)
if a == "yes":
s.send("yes")
f = open('myfile1', 'rb')
l = f.read()
while True:
for line in l:
s.send(line)
break
f.close()
else:
s.close
Why did you check a == "yes" on client side even when server is not sending "yes"
I think you can check a == "is there any other file?" insted
I currently am trying to create a client-server application in which the client can send multiple files to the server using TCP protocol. The server will eventually create a hash-algorithm and send it back to the client but I am running into issues sending multiple files from the client to the server. In it's current form, the first file sends correctly but the files after encounter an error where the information is merged together. IE the file size is listed as the second file's name. I am a javascript dude and very new to python so an explanation to how I can make this happen would be much appreciated. I believe threading is the answer but with my limited understanding of python, I do not know how to make this work. Currently I can send one file at a time and the server stays open. However, I would like to enter several file names from my current directory and have them processed. I eventually will convert the entire client side into C but I am struggling to get the server to work correctly in python. Any advice would be much appreciated!
Server.py
import socket
import hashlib
import threading
import struct
HOST = '127.0.0.1'
PORT = 2345
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(10)
print("Waiting for a connection.....")
conn, addr = s.accept()
print("Got a connection from ", addr)
while True:
hash_type = conn.recv(1024)
print('hash type: ', hash_type)
if not hash_type:
break
file_name = conn.recv(1024)
print('file name: ', file_name)
file_size = conn.recv(1024)
file_size = int(file_size, 2)
print('file size: ', file_size )
f = open(file_name, 'wb')
chunk_size = 4096
while file_size > 0:
if file_size < chunk_size:
chuk_size = file_size
data = conn.recv(chunk_size)
f.write(data)
file_size -= len(data)
f.close()
print('File received successfully')
s.close()
Client.py
import socket
import threading
import os
HOST = '127.0.0.1'
PORT = 2345
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
hash_type = input('Enter hash type: ')
files = input('Enter file(s) to send: ')
files_to_send = files.split()
for file_name in files_to_send:
s.send(hash_type.encode())
print(file_name)
s.send(file_name.encode())
file_size = os.path.getsize(file_name)
file_size = bin(file_size)
print(file_size)
s.send(file_size.encode())
f = open(file_name, 'rb')
l = f.read()
while(l):
s.send(l)
l = f.read()
f.close()
print('File Sent')
s.close()
One way to handle what you're doing is to buffer your socket data. Below is a class that buffers data and knows how to send and receive null-terminated, UTF-8-encoded strings, and raw chunks of bytes:
buffer.py:
class Buffer:
def __init__(self,s):
'''Buffer a pre-created socket.
'''
self.sock = s
self.buffer = b''
def get_bytes(self,n):
'''Read exactly n bytes from the buffered socket.
Return remaining buffer if <n bytes remain and socket closes.
'''
while len(self.buffer) < n:
data = self.sock.recv(1024)
if not data:
data = self.buffer
self.buffer = b''
return data
self.buffer += data
# split off the message bytes from the buffer.
data,self.buffer = self.buffer[:n],self.buffer[n:]
return data
def put_bytes(self,data):
self.sock.sendall(data)
def get_utf8(self):
'''Read a null-terminated UTF8 data string and decode it.
Return an empty string if the socket closes before receiving a null.
'''
while b'\x00' not in self.buffer:
data = self.sock.recv(1024)
if not data:
return ''
self.buffer += data
# split off the string from the buffer.
data,_,self.buffer = self.buffer.partition(b'\x00')
return data.decode()
def put_utf8(self,s):
if '\x00' in s:
raise ValueError('string contains delimiter(null)')
self.sock.sendall(s.encode() + b'\x00')
With this class, your client and server become:
client.py:
import socket
import threading
import os
import buffer
HOST = '127.0.0.1'
PORT = 2345
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
with s:
sbuf = buffer.Buffer(s)
hash_type = input('Enter hash type: ')
files = input('Enter file(s) to send: ')
files_to_send = files.split()
for file_name in files_to_send:
print(file_name)
sbuf.put_utf8(hash_type)
sbuf.put_utf8(file_name)
file_size = os.path.getsize(file_name)
sbuf.put_utf8(str(file_size))
with open(file_name, 'rb') as f:
sbuf.put_bytes(f.read())
print('File Sent')
server.py:
import socket
import os
import buffer
HOST = ''
PORT = 2345
# If server and client run in same local directory,
# need a separate place to store the uploads.
try:
os.mkdir('uploads')
except FileExistsError:
pass
s = socket.socket()
s.bind((HOST, PORT))
s.listen(10)
print("Waiting for a connection.....")
while True:
conn, addr = s.accept()
print("Got a connection from ", addr)
connbuf = buffer.Buffer(conn)
while True:
hash_type = connbuf.get_utf8()
if not hash_type:
break
print('hash type: ', hash_type)
file_name = connbuf.get_utf8()
if not file_name:
break
file_name = os.path.join('uploads',file_name)
print('file name: ', file_name)
file_size = int(connbuf.get_utf8())
print('file size: ', file_size )
with open(file_name, 'wb') as f:
remaining = file_size
while remaining:
chunk_size = 4096 if remaining >= 4096 else remaining
chunk = connbuf.get_bytes(chunk_size)
if not chunk: break
f.write(chunk)
remaining -= len(chunk)
if remaining:
print('File incomplete. Missing',remaining,'bytes.')
else:
print('File received successfully.')
print('Connection closed.')
conn.close()
Demo
client:
Enter hash type: abc
Enter file(s) to send: demo1.dat demo2.dat
demo1.dat
File Sent
demo2.dat
File Sent
server:
Waiting for a connection.....
Got a connection from ('127.0.0.1', 22126)
hash type: abc
file name: uploads\demo1.dat
file size: 488892
File received successfully.
hash type: abc
file name: uploads\demo2.dat
file size: 212992
File received successfully.
Connection closed.
1.
file_size = conn.recv(1024)
In your server code you read 1024 bytes as your file_size, file_size is only 4 or 8 bytes long
2.
file_name = conn.recv(1024) Your server don't know how long the filename/hashtype is.
-> Use a long for both sizes and read only sizeof(long) bytes from the stream.
You can use https://docs.python.org/2/library/struct.html for packing/encoding of these numbers
-> Or just go the easy way and use https://docs.python.org/3/library/pickle.html for serialization
I'm trying to send the contents of the c: drive back to the client. I'm using the os.listdir() function to generate the list but when I send it back to the client and try to print, I get nothing. How can I print the list that I get for os.listdir()?
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."
When doing the put command I am getting this error. I can't seem to figure out why.
line 41, in
data = client.recv(1024)
error: [Errno 10053] An established connection was aborted by the software in your host machine
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(command):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send(command)
string = command.split(' ', 1)
input_file = string[1]
with open(input_file, 'rb') as file_to_put:
for data in file_to_put:
s.sendall(data)
s.close()
return
def get(command):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send(command)
string = command.split(' ', 1)
input_file = string[1]
with open(input_file, 'wb') as file_to_get:
while True:
data = s.recv(1024)
print data
if not data:
break
file_to_get.write(data)
file_to_get.close()
s.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.close()
print "Closing connection."
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:\\') # listing contents of c: drive
client.send(str(data))
print data
else:
string = data.split(' ', 1)
data_file = string[1]
if (string[0] == 'put'):
with open(data_file, 'wb') as file_to_write: # opening sent filename to write bytes
while True:
data = client.recv(1024)
if not data:
break
file_to_write.write(data) # writing data
file_to_write.close() # closing file
break
print 'Receive Successful'
elif (string[0] == 'get'):
with open('C:\\' + data_file, 'rb') as file_to_send:
for data in file_to_send:
client.send(data)
print 'Send Successful'
client.close()
s.close()
print "Server exiting."