I'm trying to send multiple images from client to server .
from my client I send one image at a time then for each image I get the size in the server and then send the size back to client and then try and store all the sizes of all images in a table .
I wrote this code and it doesn't seem to work:
client.py:
from PIL import Image
import glob
import sys
import pickle
import socket
import os
import numpy
reload(sys)
def readFileImages(strFolderName):
st = os.path.join(strFolderName, "*.png")
print st
return glob.glob(st)
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
client_socket.bind(("127.0.0.1", 4000))
list1=readFileImages("test")
myoutput =[]
while (list1):
for im in list1:
f=open(im,"rb")
while True:
veri = f.read()
if not veri:
break
client_socket.send(veri)
f.close()
data = client_socket.recv(4096)
data_arr=pickle.loads(data)
newrow=numpy.asarray(data_arr)
myoutput=numpy.vstack([myoutput,newrow])
client_socket.close()
numpy.savetxt("testTable.csv",myoutput,delimiter=",")
server.py:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
s.bind(("127.0.0.1",4000))
s.listen(5)
client_socket, address = s.accept()
print "Connected to - ",address,"\n"
fname="test.png"
fp = open(fname,'wb')
# image
while True:
strng = client_socket.recv(1024)
if not strng:
break
fp.write(strng)
fp.close()
#T[0]=detect_carte_grise(fp)
im = Image.open(fp)
T= im.size #width,height
data=pickle.dumps(T)
client_socket.send(data)
and why do i get this error ?:[errno98] address already in use
I cannot even connect to server
First, in server code you bind to port, but in client code, you need to CONNECT to that server. You are binding in both of your scripts and address is already used by the first running script. so in client drop bind and change to client_socket.connect(("127.0.0.1", 4000)). That will resolve current issues, if you have any more, please, ask another question.
I got the same error, I Changed the "port number". It's worked fine
Related
I have created a socket client in python that is meant to receive data from socket server (which is sending data to client at constant time interval) and construct an image out of the data by using cv2 and numpy. I have tested the Socket Client and Server for echo communication for text data and it is working as expected. The Socket Server is ESP32CAM Access Point and it is also working as expected. I am facing issue when I try to write the Socket Client python code, because as the ESP32CAM Socket Server is sending data at constant time interval, the Socket Client has to be ready to receive data at that exact moment, which is the issue I have. I would like to know whether there is some concept like Interrupts in python like microcontrollers.
Here is my python code :
import socket
import sys
import time
import io
import cv2
import numpy
import numpy as np
host = "192.168.4.1"
port = 80
print('# Creating socket')
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print('Failed to create socket')
sys.exit()
print('# Getting remote IP address')
try:
remote_ip = socket.gethostbyname( host )
except socket.gaierror:
print('Hostname could not be resolved. Exiting')
sys.exit()
print('# Connecting to server, ' + host + ' (' + remote_ip + ')')
sock.connect((remote_ip , port))
print('Server Connected !')
while True:
begin = time.time()
message_chunks = []
d = ''
while True:
if time.time() - begin > 0.2: #200 ms
break
try:
d = sock.recv(4194304) #4MB data
#print(d)
except socket.timeout:
break
if d:
message_chunks.append(d)
else:
break
data = b''.join(message_chunks)
img = io.BytesIO()
img.write(data)
img.seek(0)
imgnp = numpy.array(bytearray(img.read()), dtype=np.uint8)
frame = cv2.imdecode(imgnp,-1)
cv2.startWindowThread()
cv2.namedWindow("stream", cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty("stream",cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN)
cv2.imshow("stream", frame)
I kindly request for some guidance in threading and parallel processing for this code as well.
I am trying to write a script to transmit an image over the internet using sockets (the code is shown below). When I try it on the local machine the code works fine but when I do the same with 2 different computers (1 working as a server and 1 as client) connected to the same WiFi network, they don't even connect to one another let alone transmit data. Can anyone please help?
The server code :-
import socket
import base64
import sys
import pickle
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 8487))
s.listen(5)
while True:
# After the Connection is established
(clientsocket, address) = s.accept()
print(f"Connection form {address} has been established!")
# Initiate image conversion into a string
with open("t.jpeg", "rb") as imageFile:
string = base64.b64encode(imageFile.read())
msg = pickle.dumps(string)
print("Converted image to string")
# Send the converted string via socket encoding it in utf-8 format
clientsocket.send(msg)
clientsocket.close()
# Send a message that the string is sent
print("String sent")
sys.exit()
The client code :-
import socket, pickle, base64
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 8487))
while True:
data = []
# Recieve the message
while True:
packet = s.recv(1000000)
if not packet:
break
data.append(packet)
print("Message recieved")
# Decode the recieved message using pickle
print("Converting message to a String")
string = pickle.loads(b"".join(data))
print("Converted message to String")
# Convert the recieved message to image
imgdata = base64.b64decode(string)
filename = 'tu.jpeg'
with open(filename, 'wb') as f:
f.write(imgdata)
s.shutdown()
s.close()
s.connect((socket.gethostname(), 8487))
Your client attempts to connect to the local host. If the server host is the local host this works. But if the server host is different this will of course not connect to the server. Instead you have to provide the IP address or hostname of the servers system here.
I'm trying to build a desktop streaming app. It consists of a server and a client for now. I learned that I should use the library pickle in order to serialize/deserialize the data. However, when I run both the scripts, I get the error "Pickle data was truncated" from the client side. Could you help me to solve this? I tried the solution the following link, whose OP apparently was trying to do the similar think but it didn't work.
python 3.6 socket pickle data was truncated
Server
import numpy as np
import cv2
from PIL import ImageGrab
import socket
import pickle
HOST = "0.0.0.0"
SOCKET = 5000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST,SOCKET))
while True:
s.listen(5)
client, addres = s.accept()
print(addres, " has connected")
img = ImageGrab.grab()
img_np = np.array(img)
img_np_serial = pickle.dumps(img_np)
client.send(img_np_serial)
if cv2.waitKey(1) == 27:
break
cv2.destroyAllWindows()
Client
import socket
import pickle
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostbyname(socket.gethostname()),5000))
data = b""
while True:
packet = s.recv(4096)
if not packet: break
data += packet
data_deserial = pickle.loads(data)
print((data_deserial))
I know that similar questions have been raised but they don't seem to work for me! I have tried serializing the dictionary then converting that to a string then encoding it before I send it over the socket. No success so far!
This is my server code:
#library
import socket
import pickle
#socket initialization
host = "127.0.0.1"
port = 5000
mainAddr = (host, port)
#dict initialization
dataDict = {} #just imagine that dict has content
#create socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #TCP
s.bind((mainAddr))
s.listen(4)
print('program started')
print('listening..')
while True:
try:
conn, addr = s.accept()
print("connection from: "+str(addr))
print("sending message..")
pickle.dumps(dataDict)
print('pickled!')
dataS = str(dataP)
print('stringed!')
dataE = dataS.encode('UTF-8')
print('encoded!')
s.sendto(dataE,addr)
print('data sent!')
except:
pass
s.close()
For the socket initialization, I've tried other types:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #UDP
s = socket.socket()
For the sending part, I've tried these alternatives:
s.send(dataE)
s.send(dataE,addr)
s.sendall(dataE)
s.sendall(dataE,addr)
When I run the program, these get printed out:
program started
listening..
connection from:<insert addr here>
sending message..
pickled!
stringed!
encoded!
Only data sent! is not sent. So I am guessing that it's the sending part that has a problem.
For the client side, here's the code:
#library
import socket
import pickle
#initialization
host = '127.0.0.1'
port = 5000
buffer = 1024
#create socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #TCP
s.connect((host,port))
print('connected!')
#receive dictionary
print('receiving message..')
while True:
data, addr = s.recvfrom(buffer)
print('received!')
dataD = data.decode("UTF-8")
print('decoded!')
dataP = pickle.loads(dataD)
print('unpickled!')
print(str(dataP))
s.close()
In the client terminal, only the following prints:
connected!
receiving message..
On the client side, I've tried changing the order of unpickling and decoding but still, to no avail.
A TCP server socket is not actually used for sending/receiving data; I'm surprised you're not getting an error when calling s.send() or similar on it. Instead, it's a factory for producing individual sockets for each client that connects to the server - conn, in your code. So, conn.sendall() is what you should be using. No address parameter is required, the individual socket already knows who it is talking to. (.send() is unreliable without some extra work on your part; .sendto() is only used with UDP sockets that have not been connected to a particular client.)
I am trying a little client server project to get me into network programming but I seem to have got stuck at the first hurdle. I cant seem to get past getting the first line of data only even if its a new connection.
#!/usr/bin/python
import socket
s = socket.socket()
host = '192.168.0.233' # Test Server
port = 7777
s.bind((host, port))
s.listen(5)
while True:
c, addr = s.accept()
print 'Got connection from', addr
data = c.recv(2048)
print(data)
If I telnet to the host running the server, the connection opens fine and I see on the server Got connection from addr, but I also only see the first line of data when I sent 4 lines of data,
I thought because its in a loop it should now always be looking for data?
I know im doing something wrong but unsure what.
Im using Python 2.6.6
recv needs to be in a loop too, at the moment your code is receiving some data and then waiting for a new connection.
https://docs.python.org/2/library/socket.html#example has an example of socket.recv in a loop.
Try this:
#!/usr/bin/python
import socket
import threading
def listenForClients(sock):
while True:
client, address = sock.accept()
client.settimeout(5)
threading.Thread( target = listenToClient, args = (client,address) ).start()
def listenToClient(client, address):
size = 2048
while True:
try:
data = client.recv(size)
if data:
response = "Got connection"
client.send(response)
else:
raise error('Client disconnected')
except:
client.close()
return False
def main(host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((host, port))
sock.listen(5)
listenForClients(sock)
if __name__ == "__main__":
main('192.168.0.233',7777)
Here I use a thread for each client. The problem that you have with having Socket.accept() in the loop is that it blocks meaning that concurrent access won't work and you'll only be able to talk to one client at a time.
Try running it in the background and sending it messages with:
#!/usr/bin/python
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('192.168.0.233',7777))
vwhile True:
data = raw_input("enter a message: ")
sock.send(data)
print sock.recv(2048)