The following is complete client , server and sendproc codes:
Client.py
from socket import *
import pickle
import sendproc
import struct
s = socket(AF_INET, SOCK_STREAM) # Create a socket object
host = "192.168.1.4" # Get local machine name
port = 1094 # Reserve a port for your service.
s.connect((host, port))
with open("file.txt",'rb') as f:
print ('file opened')
print('Sending file...')
for data in f:
print(data)
print("MSG sent")
sendproc.send_msg(s, data)
Server.py
from socket import *
import pickle
import sendproc
port = 1094 # Reserve port for service.
s = socket(AF_INET,SOCK_STREAM) # Create a socket object
host = "192.168.1.4" # Get local machine name
s.bind((host, port)) # Bind to the port
s.listen(5)
print('server is listening')
conn,addr = s.accept()
with open("file1.txt",'w') as fb:
print("File downloading\n",fb)
while True:
print("hi")
data = sendproc.recv_msg(conn)
print(data)
if not data:
print("No data")
break
fb.write(data)
fb.flush()
print("Download complete\n")
SendRecieveProcedure.py
import struct
def send_msg(s, msg):
msg2 = struct.pack('>I', len(msg)) + msg
s.send(msg2)
def recv_msg(s):
# Read message length and unpack it into an integer
raw_msglen = s.recv(4)
print(raw_msglen)
if not raw_msglen:
return None
n = struct.unpack('>I',raw_msglen)[0]
# Read the message data
data = ' '
while len(data) < n:
packet = s.recv(n - len(data)).decode("cp437")
if not packet:
return None
data += packet
#print("hwllo",data )
return data
output prints correctly to the console, but if I go open up the file it's only writing starting lines.so what is the problem in code
Related
I made a socket connection between a client and server. I set it up so it makes a request for data, but it doesn't receive the data. It throws Traceback (most recent call last): File "C:\...file path...\server.py", line 38, in <module> s1.connect((host1, port1)) ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it, but it sends a response. How can I set it up to receive the message? By the way, it makes a request to the server to read a file.
Server.py:
import json
import socket
import base64
while True:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024)
data = repr(data)
data = str(data)
data1 = []
for i in range(len(data)):
data1.append(data[i])
data1[0] = ""
data1[1] = ""
data1[len(data1)-1] = ""
data ="".join(data1).replace("'","\"").replace("~","=")
if (data != ""):
print(data)
data = json.loads(data)
typer = data["type"]
if (typer == 'putreq'):
#Writes to file, there are no bugs here.
else:
host1 = addr[0]
port1 = addr[1]
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s1:
s1.connect((host1, port1))
with open(data["name"], 'r') as userfile:
data1 = userfile.read()
s1.sendall(bytes(base64.b64encode(bytes(data1,'utf-8')),'utf-8'))
s1.close
s.close()
Client.py:
import socket
import sys
import base64
import json
import random
import time
typec = sys.argv[1]
filec = sys.argv[2]
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(bytes(str({"type":'namereq',"name":filec}), "UTF-8"))
data = s.recv(1024)
data = repr(data)
data = str(data)
data1 = []
for i in range(len(data)):
data1.append(data[i])
data1[0] = ""
data1[1] = ""
data1[len(data1)-1] = ""
data ="".join(data1).replace("~","=")
if(data != ''):
print(data)
I think it has to do with the hostname and port being different on the server and the user.
modify this:
else:
host1 = addr[0]
port1 = addr[1]
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s1:
s1.connect((host1, port1))
with open(data["name"], 'r') as userfile:
data1 = userfile.read()
s1.sendall(bytes(base64.b64encode(bytes(data1,'utf-8')),'utf-8'))
s1.close
into this:
else:
with open(data["name"], 'r') as userfile:
data1 = userfile.read()
conn.sendall(bytes(base64.b64encode(bytes(data1,'utf-8')),'utf-8'))
conn.close
you already have a socket connected to that host and port no need to create others (also because i can see that HOST is equal to host1)
I'm trying to send a large file (.avi) over socket by sending the content of the file in chunks (a little bit like torrents). The problem is that the script doesn't send the file. I'm out of ideas here.
Any help or twerking of the script would be very appreciated.
Server:
import socket
HOST = ""
PORT = 8050
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(1)
conn, addr = sock.accept()
print("Connected by ", str(addr))
while 1:
data = conn.recv(1024)
if data.decode("utf-8") == 'GET':
with open(downFile,'rb') as output:
l = output.read(1024)
while (l):
conn.send(l)
l = output.read(1024)
output.close()
conn.close()
Client:
import socket
HOST = "localhost"
PORT = 8050
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST,PORT))
while 1:
message = input()
sock.send(bytes(message,'UTF-8'))
conn.send(str.encode('GET'))
with open(downFile, 'wb+') as output:
while True:
rec = str(sock.recv(1024), "utf-8")
if not rec:
break
output.write(rec)
output.close()
print('Success!')
sock.close()
Here are a working client and server that should demonstrate transferring a file over a socket. I made some assumptions about what your code was supposed to do, for example, I assumed that the initial message the client sent to the server was supposed to be the name of the file to download.
The code also includes some additional functionality for the server to return an error message to the client. Before running the code, make sure the directory specified by DOWNLOAD_DIR exists.
Client:
import socket
import sys
import os
HOST = "localhost"
PORT = 8050
BUF_SIZE = 4096
DOWNLOAD_DIR = "downloads"
def download_file(s, down_file):
s.send(str.encode("GET\n" + down_file))
rec = s.recv(BUF_SIZE)
if not rec:
return "server closed connection"
if rec[:2].decode("utf-8") != 'OK':
return "server error: " + rec.decode("utf-8")
rec = rec[:2]
if DOWNLOAD_DIR:
down_file = os.path.join(DOWNLOAD_DIR, down_file)
with open(down_file, 'wb') as output:
if rec:
output.write(rec)
while True:
rec = s.recv(BUF_SIZE)
if not rec:
break
output.write(rec)
print('Success!')
return None
if DOWNLOAD_DIR and not os.path.isdir(DOWNLOAD_DIR):
print('no such directory "%s"' % (DOWNLOAD_DIR,), file=sys.stderr)
sys.exit(1)
while 1:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.connect((HOST, PORT))
except Exception as e:
print("cannot connect to server:", e, file=sys.stderr)
break
file_name = input("\nFile to get: ")
if not file_name:
sock.close()
break
err = download_file(sock, file_name)
if err:
print(err, file=sys.stderr)
sock.close()
Server:
import socket
import sys
import os
HOST = ""
PORT = 8050
BUF_SIZE = 4096
def recv_dl_file(conn):
data = conn.recv(1024)
if not data:
print("Client finished")
return None, None
# Get command and filename
try:
cmd, down_file = data.decode("utf-8").split("\n")
except:
return None, "cannot parse client request"
if cmd != 'GET':
return None, "unknown command: " + cmd
print(cmd, down_file)
if not os.path.isfile(down_file):
return None, 'no such file "%s"'%(down_file,)
return down_file, None
def send_file(conn):
down_file, err = recv_dl_file(conn)
if err:
print(err, file=sys.stderr)
conn.send(bytes(err, 'utf-8'))
return True
if not down_file:
return False # client all done
# Tell client it is OK to receive file
sent = conn.send(bytes('OK', 'utf-8'))
total_sent = 0
with open(down_file,'rb') as output:
while True:
data = output.read(BUF_SIZE)
if not data:
break
conn.sendall(data)
total_sent += len(data)
print("finished sending", total_sent, "bytes")
return True
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(1)
keep_going = 1
while keep_going:
conn, addr = sock.accept()
print("Connected by", str(addr))
keep_going = send_file(conn)
conn.close() # close clien connection
print()
sock.close() # close listener
I'm new to python socket programming. I want to transfer 5 files (photos) from one host in mininet to another. The name of these files are numbered respectively (I mean 1.jpg, 2.jpg and ...). The problem is that when I run these codes, the first photo is transferred correctly but others become corrupted. What's the problem:
sender.py
import socket
import sys
buf = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('10.0.0.1',12345))
for i in range(1,6):
with open("%d.jpg" % (i),'rb') as f:
data = f.read(buf)
while 1:
if not data:
break
s.sendall(data)
data = f.read(buf)
s.close()
receiver.py:
import socket
import sys
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('10.0.0.1', 12345))
buf = 1024
s.listen(1)
conn , addr = s.accept()
for i in range(6,11):
with open("%d.jpg" % (i),'wb') as f:
while 1:
data = conn.recv(buf)
#print(data[:10])
#print "PACKAGE RECEIVED..."
f.write(data)
if not data: break
#conn.close()
#s.close()
The simple solution to your problem is to create a new connection for each file. The code below does that.
Sender
from __future__ import print_function
import socket
HOST = 'localhost'
PORT = 12345
BUFSIZE = 4096
def send_file(fname):
with open(fname, 'rb') as f:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.connect((HOST, PORT))
except socket.error as err:
print(err, HOST, PORT)
sock.close()
return
while True:
data = f.read(BUFSIZE)
if not data:
break
while data:
sent = sock.send(data)
data = data[sent:]
sock.close()
fnames = [
'test0.jpg',
'test1.jpg',
'test2.jpg',
'test3.jpg',
]
def main():
for fname in fnames:
send_file(fname)
if __name__ == '__main__':
main()
Receiver
from __future__ import print_function
import socket
HOST = 'localhost'
PORT = 12345
BUFSIZE = 4096
def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
sock.bind((HOST, PORT))
except socket.error as err:
print('Bind failed', err)
return
sock.listen(1)
print('Socket now listening at', HOST, PORT)
file_number = 0
try:
while True:
conn, addr = sock.accept()
print('Connected with', *addr)
fname = 'image%d.jpg' % file_number
with open(fname, 'wb') as f:
while True:
data = conn.recv(BUFSIZE)
if not data:
break
f.write(data)
conn.close()
print(fname, 'saved\n')
file_number += 1
# Hit Break / Ctrl-C to exit
except KeyboardInterrupt:
print('\nClosing')
sock.close()
if __name__ == '__main__':
main()
You need to hit CtrlC or Break (depending on your OS) to exit the receiver.
But using those numeric file names at the receiver isn't very satisfactory , so I decided to make it a little more complicated. :) In the following version we send the file name before the file data. That's slightly tricky because the receiver needs to separate the file name from the actual file data. If each socket.recv call corresponded to a socket.send call that would be easy, but that's not guaranteed to happen: the received bytes may be split differently from how they were sent. The receiver needs to buffer the bytes so it can break them up correctly. See the Socket Programming HOWTO for details.
So that the receiver knows where the file name ends we first send a single byte that encodes the length of the file name. A byte can hold a number from 0 to 255, so this code can't handle file names longer than that. After the length byte, we send the file name itself, encoded using UTF-8. And then we send the actual file contents.
The receiver uses a class named Receiver to handle the buffering. This class has a .get method which we can use to get a specified number of bytes. We use that method to get the file name length and the file name. And then we use Receiver's .save method to save the received file contents to a new file.
This code is a little bit messy because it's designed to run on Python 2 and Python 3, in any combination. It'd be somewhat neater if it was for Python 3 only. I hard-coded 'localhost' as the host name, since I only have one computer, so I couldn't test it over a network, but I'm confident that it will work correctly on a network.
Here's the sender:
from __future__ import print_function
import socket
from struct import pack
HOST = 'localhost'
PORT = 12345
BUFSIZE = 4096
def send(sock, data):
while data:
sent = sock.send(data)
data = data[sent:]
def send_file(fname):
with open(fname, 'rb') as f:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.connect((HOST, PORT))
except socket.error as err:
print(err, HOST, PORT)
sock.close()
return
# Send the file name length & the filename itself in one packet
send(sock, pack('B', len(fname)) + fname.encode())
while True:
data = f.read(BUFSIZE)
if not data:
break
send(sock, data)
sock.close()
fnames = [
'test1.gif',
'test2.jpg',
'test3.png',
'test4.pdf',
]
def main():
for fname in fnames:
send_file(fname)
if __name__ == '__main__':
main()
And here's the receiver:
from __future__ import print_function
import socket
from struct import unpack
HOST = 'localhost'
PORT = 12345
BUFSIZE = 4096
class Receiver:
''' Buffer binary data from socket conn '''
def __init__(self, conn):
self.conn = conn
self.buff = bytearray()
def get(self, size):
''' Get size bytes from the buffer, reading
from conn when necessary
'''
while len(self.buff) < size:
data = self.conn.recv(BUFSIZE)
if not data:
break
self.buff.extend(data)
# Extract the desired bytes
result = self.buff[:size]
# and remove them from the buffer
del self.buff[:size]
return bytes(result)
def save(self, fname):
''' Save the remaining bytes to file fname '''
with open(fname, 'wb') as f:
if self.buff:
f.write(bytes(self.buff))
while True:
data = self.conn.recv(BUFSIZE)
if not data:
break
f.write(data)
def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
sock.bind((HOST, PORT))
except socket.error as err:
print('Bind failed', err)
return
sock.listen(1)
print('Socket now listening at', HOST, PORT)
try:
while True:
conn, addr = sock.accept()
print('Connected with', *addr)
# Create a buffer for this connection
receiver = Receiver(conn)
# Get the length of the file name
name_size = unpack('B', receiver.get(1))[0]
# Get the file name itself
name = receiver.get(name_size).decode()
print('name', name)
# Save the file
receiver.save(name)
conn.close()
print('saved\n')
# Hit Break / Ctrl-C to exit
except KeyboardInterrupt:
print('\nClosing')
sock.close()
if __name__ == '__main__':
main()
You should use it like:
with open("%d.jpg" % (i),'wb') as f:
while 1:
data = conn.recv(buf)
#print(data[:10])
#print "PACKAGE RECEIVED..."
f.write(data)
if not data: break
this way f gets closed automatically when you leave the with block when you exit the while.
I guess you need to extend the protocol so that the receiver knows what it gets and that you can let it act on that. Something like a 'begin-of-transfer' ... sending the filename, sending the data, sending 'end-of-transfer' that makes the receiver close the file
The problem I'm having is to get a file from the server. Lets say I want to
"get ./testing.pdf" which sends the pdf from the server to the client. It sends but it is always missing bytes. Is there any problems with how I am sending the data. If so how can I fix it? I left out the code for my other functionalities since they are not used for this function.
server.py
import socket, os, subprocess # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
#host = ''
port = 5000 # Reserve a port for your service.
bufsize = 4096
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
while True:
c, addr = s.accept() # Establish connection with client.
print 'Got connection from', addr
while True:
userInput = c.recv(1024)
.... CODE ABOUT OTHER FUNCTIONALITY
elif userInput.split(" ")[0] == "get":
print "inputed get"
somefile = userInput.split(" ")[1]
size = os.stat(somefile).st_size
print size
c.send(str(size))
bytes = open(somefile).read()
c.send(bytes)
print c.recv(1024)
c.close()
client.py
import socket, os # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
#host = '192.168.0.18'
port = 5000 # Reserve a port for your service.
bufsize = 1
s.connect((host, port))
print s.recv(1024)
print "Welcome to the server :)"
while 1 < 2:
userInput = raw_input()
.... CODE ABOUT OTHER FUNCTIONALITY
elif userInput.split(" ")[0] == "get":
print "inputed get"
s.send(userInput)
fName = os.path.basename(userInput.split(" ")[1])
myfile = open(fName, 'w')
size = s.recv(1024)
size = int(size)
data = ""
while True:
data += s.recv(bufsize)
size -= bufsize
if size < 0: break
print 'writing file .... %d' % size
myfile = open('Testing.pdf', 'w')
myfile.write(data)
myfile.close()
s.send('success')
s.close
I am trying to receive an image from Android to PC using socket in Python. My server code is as follows:
import socket
address = ("10.0.0.12", 5000)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(address)
s.listen(1000)
client, addr = s.accept()
print 'got connected from', addr
filename = open('tst.jpg', 'wb')
while True:
strng = client.recv(1024)
if not strng:
break
filename.write(strng)
filename.close()
print 'received, yay!'
client.close()
And it returns me a tst.jpg which is the same size of that on my Android. But I cannot open the pic.
Here is my Android code:
Socket photoSocket = new Socket(ipString, port);
DataOutputStream dos = new DataOutputStream(photoSocket.getOutputStream());
FileInputStream fis = new FileInputStream(PhotoActivity.filePath);
int size = fis.available();
byte[] data = new byte[size];
fis.read(data);
dos.writeInt(size);
dos.write(data);
dos.flush();
dos.close();
fis.close();
photoSocket.close();
so the android code is sending the size as int in front of the data, but the python code doesn't read it.
import socket
import struct
address = ("10.0.0.12", 5000)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(address)
s.listen(1000)
client, addr = s.accept()
print 'got connected from', addr
buf = ''
while len(buf)<4:
buf += client.recv(4-len(buf))
size = struct.unpack('!i', buf)
print "receiving %s bytes" % size
with open('tst.jpg', 'wb') as img:
while True:
data = client.recv(1024)
if not data:
break
img.write(data)
print 'received, yay!'
client.close()