socket programming for transferring a photo in python - python

I'm new to socket programming in python. Here is an example of opening a TCP socket in a Mininet host and sending a photo from one host to another. In fact I have changed the code which I used to send a simple message to another host (writing the received data to a text file) in order to meet my requirements.
But when I run this code, I encounter this error at sender side:
144
Traceback (most recent call last):
File mmyClient2,pym, line 13, in <module>
if(s.sendall(data)):
File m/usr/lib/python2.7/socket.pym, line 228, in meth
return yetattr[self,_sockename](*args)
File m/usr/lib/python2.7/socket.pym, line 174, in _dummy
raise error(EBADF, 'Bad file descriptor')
socket,error: [Errno 9] Bad file descriptor
So what's wrong?
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
f = open("2.jpg",'wb')
s.listen(1)
conn , addr = s.accept()
while 1:
data = conn.recv(buf)
print(data[:10])
#print "PACKAGE RECEIVED..."
f.write(data)
if not data: break
#conn.send(data)
conn.close()
s.close()
Sender.py:
import socket
import sys
f=open ("1.jpg", "rb")
print sys.getsizeof(f)
buf = 1024
data = f.read(buf)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('10.0.0.1',12345))
while (data):
if(s.sendall(data)):
#print "sending ..."
data = f.read(buf)
#print(f.tell(), data[:10])
s.close()
There seems to be a problem with s.sendall(), because when I change it to s.send(), there is no error and photo transfer is successful. So my question is: Although I was suggested to use s.sendall() instead of s.send() in my previous question on this site, Is it wrong not to do this?

After send all data, you closed socket.And use closed socket again, that cause error.You can write sender like this.
import socket
import sys
f=open ("1.jpg", "rb")
print sys.getsizeof(f)
buf = 1024
data = f.read(buf)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('10.0.0.1',12345))
while 1:
if not data:
break
s.sendall(data)
data = f.read(buf)
s.close()

Related

ipv6 python sockets not working ! OSError: [Errno 22] Invalid argument

I have a simple client server program and the server side works but for some reason I can't get the the client to interact to the server. I am able to launch the server and use nc -6 fe80::cbdd:d3da:5194:99be%eth1 2020 and connect to it.
Server code:
#!/usr/bin/env python3
from socket import *
from time import ctime
HOST='::'
PORT = 2020
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpSerSock = socket(AF_INET6, SOCK_STREAM)
##tcpSerSock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)
while True:
print('Waiting for connection...')
tcpCliSock, addr = tcpSerSock.accept()
print('...connected from:', addr)
while True:
data = tcpCliSock.recv(BUFSIZ)
if not data:
break
tcpCliSock.send(('[%s] %s'%(bytes(ctime(), 'utf-8'), data)).encode('utf-8'))
tcpCliSock.close()
tcpSerSock.close()
client code:
#!/usr/bin/python3
from socket import *
def tcp_ipv6():
HOST = 'fe80::cbdd:d3da:5194:99be%eth1'
PORT = 2020
ADDR = (HOST, PORT)
BUFSIZ = 1024
sock = socket(AF_INET6, SOCK_STREAM)
sock.connect(ADDR)
while True:
data = input('> ')
if not data:
break
sock.send(data)
response = sock.recv(BUFSIZ)
if not response:
break
print(response.decode('utf-8'))
sock.close()
tcp_ipv6()
When I run the client code I get:
Traceback (most recent call last):
File "client.py", line 44, in <module>
tcp_ipv6()
File "client.py", line 31, in tcp_ipv6
sock.connect(ADDR)
OSError: [Errno 22] Invalid argument
Edit1:
Thanks to Establishing an IPv6 connection using sockets in python
4-tuple for AF_INET6
ADDR = (HOST, PORT, 0, 0)
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM, 0)
sock.connect(ADDR)
Still having the same error
Any idea?
Thanks in advance
Some parts of your question have been asked before.
Establishing an IPv6 connection using sockets in python
However, it is not the entire reason why it is not working correctly. If you look at your IPv6 address. fe80::cbdd:d3da:5194:99be%eth1 You can see the %eth1 at the end. That is not part of the internet address. Change HOST to HOST = 'fe80::cbdd:d3da:5194:99be'. And it should work.
I would also like to point out another error in your code. You are attempting to send a string (received from input) over the socket. However, this method only accepts byte like objects. You can add data = data.encode('utf-8') to fix this.
The higher level function - create_connection , to connect to port works in such case. Sample scriptlet is given as follows. Though why sock.connect fails needs to be identified.
HOST = "xxxx::xxx:xxxx:xxxx:xxxx%en0"
PORT = 2020
ADDR = (HOST, PORT)
BUFSIZ = 1024
sock=create_connection(ADDR)

sending file through socket in python 3

In the code below I've tried to send an image using the python socket module in one machine to another machine. So I have 2 files: client.py and Server.py
as I figured it out the problem is when I read the image(as bytes) at the client machine and then the server tries to receive the file, at that moment when sending process is done before the receiving process then the error below occurs at line 13 of the client code:
BrokenPipeError: [Errno 32] Broken pipe
I want to find out what this error is and why does it occur in my code.
Server.py
import socket
host = '192.168.1.35'
port = 5000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(1)
while True:
conn , addr = s.accept()
data = conn.recv(1024)
with open(r"C:\Users\master\Desktop\music.jpg",'wb') as f:
f.write(data)
# conn.send(b'done')
data = conn.recv(1024)
if not data:
break
conn.send(b'done')
conn.send(b'done')
conn.close()
s.close()
Client.py
import socket
def main():
HOST = '192.168.1.35'
PORT = 5000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
f = open('/home/taha/Desktop/f.jpg','rb')
data = f.read()
s.sendfile(f)
if s.recv(1024) == b'done':
f.close()
s.close()
if __name__ == '__main__':
main()
You are closing the server connection before the client read the “done”

Failed to send bytes over sockets: Message too long

SOLVED using the following:
Python Socket Receive Large Amount of Data
I have server and client. I try to send bytes over sockets from client to server. However, when it actually tries to send the bytes, it failed with error: socket.error errno 90 message too long. Is there any way to get over this error?
Client:
from socket import socket, AF_INET, SOCK_DGRAM
import pyscreenshot as ImageGrab
SERVER = 'xxxx.xxxx.xxxx.xxxx'
PORT = 5000
mySocket = socket(AF_INET, SOCK_DGRAM)
while True:
im = ImageGrab.grab(bbox=(0,27,320,266))
im.save('test.png')
myfile = open('test.png')
bytes = myfile.read()
mySocket.sendto(bytes, (SERVER, PORT))
myfile.close()
Server:
from socket import socket, gethostbyname, AF_INET, SOCK_DGRAM
import cv2
from PIL import Image
import io
PORT_NUMBER = 5000
SIZE = 150000
hostName = gethostbyname( '0.0.0.0' )
mySocket = socket(AF_INET, SOCK_DGRAM)
mySocket.bind((hostName, PORT_NUMBER))
while True:
(data, addr) = mySocket.recvfrom(SIZE)
image = Image.open(io.BytesIO(data))
image.save('test.png')
imga = cv2.imread('test.png', 0)
sys.exit()
So now I use TCP connection.
New client:
from socket import socket, AF_INET, SOCK_STREAM
import pyscreenshot as ImageGrab
SERVER = 'xxxx.xxxx.xxxx.xxxx'
PORT = 5000
mySocket = socket(AF_INET, SOCK_STREAM)
mySocket.connect((SERVER, PORT))
while True:
im = ImageGrab.grab(bbox=(0,27,320,266))
im.save('test.png')
myfile = open('test.png')
bytes = myfile.read()
mySocket.sendall(bytes)
myfile.close()
New Server:
from socket import socket, gethostbyname, AF_INET, SOCK_STREAM
import cv2
from PIL import Image
import io
import time
PORT_NUMBER = 5000
SIZE = 150000
hostName = gethostbyname( '0.0.0.0' )
mySocket = socket(AF_INET, SOCK_STREAM)
mySocket.bind((hostName, PORT_NUMBER))
mySocket.listen(1)
conn, addr = mySocket.accept()
print("Test server listening on port {0}\n".format(PORT_NUMBER))
while True:
data = conn.recv(SIZE)
last_time = time.time()
image = Image.open(io.BytesIO(data))
image.save('test.png')
imga = cv2.imread('test.png', 0)
print('loop took {} seconds'.format(time.time() - last_time))
sys.exit()
So when I try to run both, I get the following error:
(important: when i send over the sockets small amount of bytes it is successfuly sent, but when it's quite big amount of bytes the following error occurs)
C:\Users\Tal\test\Scripts\python.exe
C:/Users/Tal/PycharmProjects/test/tester.py
Test server listening on port 5000
Traceback (most recent call last):
File "C:\Users\Tal\test\lib\site-packages\PIL\ImageFile.py", line 221, in load
s = read(self.decodermaxblock)
File "C:\Users\Tal\test\lib\site-packages\PIL\PngImagePlugin.py", line 621, in load_read
cid, pos, length = self.png.read()
File "C:\Users\Tal\test\lib\site-packages\PIL\PngImagePlugin.py", line 115, in read
length = i32(s)
File "C:\Users\Tal\test\lib\site-packages\PIL\_binary.py", line 77, in i32be
return unpack_from(">I", c, o)[0]
struct.error: unpack_from requires a buffer of at least 4 bytes
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:/Users/Tal/PycharmProjects/test/tester.py", line 23, in <module>
image.save('test.png')
File "C:\Users\Tal\test\lib\site-packages\PIL\Image.py", line 1935, in save
self.load()
File "C:\Users\Tal\test\lib\site-packages\PIL\ImageFile.py", line 227, in load
raise IOError("image file is truncated")
OSError: image file is truncated
Process finished with exit code 1

Python sockets. OSError: [Errno 9] Bad file descriptor

It's my client:
#CLIENT
import socket
conne = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conne.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
i=0
while True:
conne.connect ( ('127.0.0.1', 3001) )
if i==0:
conne.send(b"test")
i+=1
data = conne.recv(1024)
#print(data)
if data.decode("utf-8")=="0":
name = input("Write your name:\n")
conne.send(bytes(name, "utf-8"))
else:
text = input("Write text:\n")
conne.send(bytes(text, "utf-8"))
conne.close()
It's my server:
#SERVER
import socket
counter=0
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('', 3001))
sock.listen(10)
while True:
conn, addr = sock.accept()
data = conn.recv(1024)
if len(data.decode("utf-8"))>0:
if counter==0:
conn.send(b"0")
counter+=1
else:
conn.send(b"1")
counter+=1
else:
break
print("Zero")
conn.send("Slava")
conn.close()
))
After starting Client.py i get this error:
Traceback (most recent call last): File "client.py", line 10, in
conne.connect ( ('127.0.0.1', 3001) ) OSError: [Errno 9] Bad file descriptor
Problem will be created just after first input.
This program - chat. Server is waiting for messages. Client is sending.
There are a number of problems with the code, however, to address the one related to the traceback, a socket can not be reused once the connection is closed, i.e. you can not call socket.connect() on a closed socket. Instead you need to create a new socket each time, so move the socket creation code into the loop:
import socket
i=0
while True:
conne = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conne.connect(('127.0.0.1', 3001))
...
Setting socket option SO_BROADCAST on a stream socket has no affect so, unless you actually intended to use datagrams (UDP connection), you should remove the call to setsockopt().
At least one other problem is that the server closes the connection before the client sends the user's name to it. Probably there are other problems that you will find while debugging your code.
Check if 3001 port is still open.
You have given 'while True:' in the client script. Are you trying to connect to the server many times in an infinite loop?

There is an error in the class do not understand written with python

I get the following error when I want to run this code. I made a mistake I do not understand where all the normal
Where do you think the error
import socket,time
import thread
class http():
def __init__(self):
self.socket = socket
self.port = 5000
self.buffsize = 1024
self.listen = 5
self._header = ("HTTP/1.1 200 OK\r\n"
"Content-Type: text/html; charset=utf-8\r\n\r\n")
def _worker(self,socket,sleep):
# Client connect for thread worker
while True:
time.sleep(sleep)
client,address = socket.accept()
data = client.recv(1024)
if data:
client.send(self._header)
client.send(data)
client.close()
def httpHandler(self):
# Create Socket For Connection
try:
self.socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.socket.bind(('127.0.0.1',self.port))
self.socket.listen(self.listen)
self.socket.setblocking(False)
except socket.error as error:
print error
finally:
print "HTTP Server Running - 127.0.0.1:5000"
self._worker(self.socket,1)
if __name__ == "__main__":
application = http()
application.httpHandler()
When I want to run on the terminal, the error
but how can it be said there is the problem of self-
HTTP Server Running - 127.0.0.1:5000
Traceback (most recent call last):
File "/Users/batuhangoksu/http.py", line 44, in <module>
application.httpHandler()
File "/Users/batuhangoksu/http.py", line 40, in httpHandler
self._worker(self.socket,1)
File "/Users/batuhangoksu/http.py", line 22, in _worker
client,address = socket.accept()
AttributeError: 'module' object has no attribute 'accept'
Use self.socket, not socket:
client,address = self.socket.accept()
socket is the name of the module. self.socket is a socket._socketobject, the value returned by a call to socket.socket. Verily, there are too many things named "socket" :).
I suggest changing self.socket to something else to help separate the ideas.
You also need to save the return value when you call socket.socket. Currently, you have
self.socket = socket
which sets the instance attribute self.socket to the module socket. That's not useful, since you can already access the module with plain old socket. Instead, use something like
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
import multiprocessing as mp
import socket
import time
HOST = '' # Symbolic name meaning all available interfaces
PORT = 50007 # Arbitrary non-privileged port
def server():
header = ("HTTP/1.1 200 OK\r\n"
"Content-Type: text/html; charset=utf-8\r\n\r\n")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(5)
while True:
conn, addr = s.accept()
data = conn.recv(1024)
if not data: break
conn.send(header)
conn.send(data)
conn.close()
def client():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send('Hello, world')
data = s.recv(1024)
s.close()
print 'Received', repr(data)
sproc = mp.Process(target = server)
sproc.daemon = True
sproc.start()
while True:
time.sleep(.5)
client()

Categories

Resources