In python3 when sending string over UDP, it has to be in form of bytes. It results with sending string "abc" like b'abc'. I want to send pure string like in python2.
Ia am using the code like this:
myInput = "abc"
mysocket.sendto(bytearray(myInput, 'utf-8'), (IP_address, port))
what the socket sends is
b'abc'
I know I can recieve it with decode:
msg, sender_address = mysocket.recvfrom(buf)
print(msg.decode())
However, I will have to recieve it with external device so I have to send it like:
abc
not
b'abc'
Related
Actually, I want to send integers through the server to client and vice versa. So that I can apply some operations on them on the client/server side. But whenever I a try to send integers, the server or client gets automatically destroyed even without sending the message. I have also used a while loop but it's not working as it was supposed to do?
Also, it works fine when I send strings (encoded)
--->server side<----
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print("--------------->SERVER<-----------------")
ip = "127.0.0.1"
port = 8080
s.bind((ip,port))
s.listen(2)
conn,addr = s.accept()
print("CONNECTED WITH THE CLIENT\n")
while True:
#for sending message
temp_msg = input("SERVER - ")
message = int(temp_msg.encode())
conn.send(message)
#for receiving message
rec_msg = conn.recv(1024)
print("CLIENT - ",rec_msg, " type = ", type(rec_msg))
---> client side <----
import socket
print("--------->CLIENT<----------------")
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ip = "127.0.0.1"
port = 8080
s.connect((ip,port))
print("CLIENT1 IS CONNECTED TO THE SERVER")
while True:
#for receiving message
rec_msg = s.recv(1024)
rec_msg = rec_msg
print("SERVER - ", rec_msg," type = ", type(rec_msg))
#for sending message
temp_msg = input("CLIENT - ")
message = int(temp_msg)
s.send(message)
----> output of client side code after sending the initial message through server.py<------
--------->CLIENT<----------------
CLIENT1 IS CONNECTED TO THE SERVER
SERVER - b'' type = <class 'bytes'>
CLIENT -
I found a very simple method to send integer by converting them to string before sending, and then change back to to the integer format after receiving them through a socket.
You can do this by following the below method.
#server side:
num=123
# convert num to str, then encode to utf8 byte
tcpsocket.send(str(num).encode('utf8'))
#client side
data = tcpsocket.recv(1024)
# decode to unicode string
strings = data.decode('utf8')
#get the num
num = int(strings)
I am using Python3 to forward incoming data form a tcp connection to a character device.
The code below is the part where I receive the data from the tcp stream. The data should all be interpreted as ASCII. Once a datagram of shape [...] is complete it should be sent to a character device file.
def tcp2devWorker(devwrt,tcp):
tcp2devbuf="";
while (1):
chunk=str(tcp.recv(64));
for b in range(len(chunk)):
if chunk[b]=="[":
tcp2devbuf="[";
elif chunk[b]=="]":
tcp2devbuf+="]";
print("From TCP: ",tcp2devbuf);
devwrt.write(tcp2devbuf);
devwrt.flush();
else:
tcp2devbuf+=str(chunk[b]);
Print shows 'b' in front of every chunk. I thought it is an artifact of print. But is also shows in the character device. Output of print:
From TCP: [)!!!!!!!!!!!!!!|SEFMTE8K#######################################'b'################################################################'b'################################################################'b'################################################################'b'#############################################################]
I read it has to do with the encoding but I dont get the concept right. Whatever way I encode and decode, can cannot get rid of the 'b's.
Can somebody point me at what I am missing?
If you just want to remove 'b' from tcp2devbuf. Then you can use tcp2devbuf.replace("'b'","").
Like this
def tcp2devWorker(devwrt,tcp):
tcp2devbuf="";
while (1):
chunk=str(tcp.recv(64));
for b in range(len(chunk)):
if chunk[b]=="[":
tcp2devbuf="[";
elif chunk[b]=="]":
tcp2devbuf+="]";
tcp2tcp2devbuf = devbuf.replace("'b'","") # <---
print("From TCP: ",tcp2devbuf);
devwrt.write(tcp2devbuf);
devwrt.flush();
else:
tcp2devbuf+=str(chunk[b]);
Intro
I am using python3 and scapy to modify and resend a captured packet.
The issue
When I send the modified payload in the Raw section the \r and \n parts of the message are not interpreted as special characters. Instead they are included as strings as shown in the cmd and wireshark screenshots below.
Current Payload
Expected Payload
This is a correct packet format captured on the network.
The packet displayed in wireshark is the following:
SIP/2.0 486 Busy Here
Via: SIP/2.0/UDP 192.168.1.5:5060;branch=z9hG4bK226016822;received=192.168.1.5;rport=5060
From: sip:301#192.168.1.2;tag=2032604445
To: sip:300#192.168.1.2;tag=as1b0290be
Call-ID: 338695025
CSeq: 21 INVITE
Server: Asterisk PBX 16.10.0
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces, timer
X-Asterisk-HangupCause: Call Rejected
X-Asterisk-HangupCauseCode: 21
Content-Length: 0
The code
This is the code so far:
from scapy.all import sniff, Ether, IP, UDP, sendp, ICMP, rdpcap,Raw
import scapy.fields
import re
import codecs
import argparse
def traffic_parser(packet):
BUSY_1 = 'SIP/2.0 486 Busy Here'
BUSY_2 = 'X-Asterisk-HangupCause: Call Rejected\\\\r\\\\nX-Asterisk-HangupCauseCode: 21'
payload = packet[3].command()
print(bytes(payload))
header=re.findall("Ringing", payload)
if header:
eth_attributes={}
eth_attributes['dst']=packet[0].dst
eth_attributes['src']=packet[0].src
eth_attributes['type']=packet[0].type
eth = Ether_layer(eth_attributes)
udp_attributes={}
udp_attributes['sport']=packet[2].sport
udp_attributes['dport']=packet[2].dport
udp_attributes['len']=444
udp = UDP_layer(udp_attributes)
# Implement packet modification
payload = payload.replace("SIP/2.0 180 Ringing", BUSY_1, 1)
payload = re.sub("Contact\:.*>", BUSY_2, payload,1)
payload = payload.replace("Raw(load=b\'", '', 1)
payload = re.sub("\'\)$", '', payload, 1)
for incr in range(1,5):
ip_attributes={}
ip_attributes['version']=packet[1].version
ip_attributes['tos']=packet[1].tos
ip_attributes['len']=464
ip_attributes['id']=0 #Zero is handled by scapy on send by default
ip_attributes['flags']=packet[1].flags
ip_attributes['frag']=packet[1].frag
ip_attributes['ttl']=packet[1].ttl
ip_attributes['proto']=packet[1].proto
ip_attributes['src']=packet[1].src
ip_attributes['dst']=packet[1].dst
ip = IP_layer(ip_attributes)
sendp(eth/ip/udp/Raw(load=payload))
print(payload)
print(Raw(load=payload))
print("\n")
def Ether_layer(attributes):
layer2=Ether()
layer2.dst=attributes['dst']
layer2.src=attributes['src']
layer2.type=attributes['type']
return layer2
def IP_layer(attributes):
layer3=IP()
layer3.version=attributes['version']
layer3.tos=attributes['tos']
layer3.len=attributes['len']
layer3.id=attributes['id']
layer3.flags=attributes['flags']
layer3.frag=attributes['frag']
layer3.ttl=attributes['ttl']
layer3.proto=attributes['proto']
layer3.src=attributes['src']
layer3.dst=attributes['dst']
return layer3
def UDP_layer(attributes):
layer4=UDP()
layer4.sport=attributes['sport']
layer4.dport=attributes['dport']
layer4.len=attributes['len']
return layer4
parser = argparse.ArgumentParser(description="rtp replay script. Arguments: -i <interface> -f <sniff filter> -o <sniff outputfile> Interface defaults to 'eth0' and filter defaults to 'udp and port 5060'")
parser.add_argument('-i', "--interface", default="eth0", help="interface to use for sniffing")
parser.add_argument('-f', '--filter', default="udp and port 5060", help="filter to be used in scapy")
parser.add_argument('-o', "--outfile", help="output file (optional)")
parser.add_argument('-t', "--testfile", help="parse test file (optional)")
args=parser.parse_args()
if __name__ == '__main__':
if args.testfile:
packets = rdpcap(args.testfile)
for packet in packets:
traffic_parser(packet)
else:
sniff(iface=args.interface, prn=traffic_parser, filter="udp and port 5060", store=0)
Q
How can I attach the payload in the desired form?
Edit:
This pcap file can be used for testing. pcap_file
Ιndicative script execution:
sudo python byespam.py -t <filename.pcapng>
To be able to use the payload as a string you need to convert it to one and also ensure that you have the correct encoding.
In your case you should:
You should only get only the load part of the Raw from scapy.packet.Packet.
Encode the load part as UTF-8 so that Python interprets correctly the special characters.
Here is some working code for your case:
payload = packet[UDP].payload.load *
payload = payload.decode("utf-8")
then you can print the payload and it will get interpreted "correctly".
* I used UDP because in your script and the pcapng file you have only UDP packets. If there were TCP packets you should use payload = packet[TCP].payload.load
\r and \n are interpreted as literal strings because you've escaped them
Here's your string:
>>> BUSY_2 = 'X-Asterisk-HangupCause: Call Rejected\\\\r\\\\nX-Asterisk-HangupCauseCode: 21'
>>> print(BUSY_2)
X-Asterisk-HangupCause: Call Rejected\\r\\nX-Asterisk-HangupCauseCode: 21
Here's the same string, but without the escape:
>>> BUSY_2 = 'X-Asterisk-HangupCause: Call Rejected\r\nX-Asterisk-HangupCauseCode: 21'
>>> print(BUSY_2)
X-Asterisk-HangupCause: Call Rejected
X-Asterisk-HangupCauseCode: 21
I tried to create a server that receives commands from the client
And to identify which command the client wrote I used if & elif
But when I run the program and write a command from the client, only the first command works (the command on the if) and if I try another command (from elif & else)
The system just doesn't respond (like she's waiting for something)
The Server Code:
import socket
import time
import random as rd
soc = socket.socket()
soc.bind(("127.0.0.1", 7777))
soc.listen(5)
(client_socket, address) = soc.accept()
if(client_socket.recv(4) == b"TIME"):
client_socket.send(time.ctime().encode())
elif(client_socket.recv(4) == b"NAME"):
client_socket.send(b"My name is Test Server!")
elif(client_socket.recv(4) == b"RAND"):
client_socket.send(str(rd.randint(1,10)).encode())
elif(client_socket.recv(4) == b"EXIT"):
client_socket.close()
else:
client_socket.send(b"I don't know what your command means")
soc.close()
The Client Code:
import socket
soc = socket.socket()
soc.connect(("127.0.0.1", 7777))
client_command_to_the_server = input("""
These are the options you can request from the server:
TIME --> Get the current time
NAME --> Get the sevrer name
RAND --> Get a Random int
EXIT --> Stop the connect with the server
""").encode()
soc.send(client_command_to_the_server)
print(soc.recv(1024))
soc.close()
if(client_socket.recv(4) == b"TIME"):
client_socket.send(time.ctime().encode())
This will check the first 4 byte received from the server
elif(client_socket.recv(4) == b"NAME"):
client_socket.send(b"My name is Test Server!")
This will check the next 4 bytes received from the server. Contrary to what you assume it will not check the first bytes again since you called recv to read more bytes. If there are no more bytes (likely, since the first 4 bytes are already read) it will simply wait. Instead of calling recv for each comparison you should call recv once and then compare the result against the various strings.
Apart from that: recv will only return up to the given number of bytes. It might also return less.
In Python, I am trying to build a simple server/client application that sends video bytes to the client.
I have been trying to figure this out for months.
The server is listening to a connection, and is receiving this much data every second, length of 1316
for example:
data = sock_reciever.recv(16000000)
If I print data, I get this:
b'G\x05\x14\x1e\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffG\x05\x14\x1f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffG\x05\x14\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffG\x05\x14\x11\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffG\x05\x14\x12\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffG\x05\x14\x13\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffG\x05\x17\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\xff\xe0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
As this comes in, I can send it back out via sock_sender.sendto(data, (SENDMCAST_GRP, SENDMCAST_PORT)), and watch the video in VLC player.
Ultimately, I want to take this data and send it to the client through the socket via conn.send(data).
However, on the client side, I believe data is coming in in the wrong order.
I've compared the data between server and client and it appears to be the same, but it builds up on the client side, which might be causing some sort of overflow.
On the client side, I take the data coming in with data = sock_reciever.recv(16000000) and send it back out via sock_sender.sendto(data, (SENDMCAST_GRP, SENDMCAST_PORT)).
But I do not get the same results on the client side, as on the server side.
How do I add headers to this data to ensure it arrives to the client in sequential order?
If possible, please explain this to me like you would explain what oxygen is to a fish.
Which Sockets I Am Using
I am trying to use TCP sockets between server and client. I thought using a stream socket would be more reliable, but I might be wrong, the only reason being that I would like to do a reverse connection, so that the client connects to the server and then receives data.
I am also using sock_sender.sendto(data, (SENDMCAST_GRP, SENDMCAST_PORT)) just to relay the incoming data on the client side, it is not the actual connection between server and client.
The socket used for the communication between server/client
is called sock_client.
This is the server-side code:
sock_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# recieves connection from client
conn, address = sock_client.accept()
# sends data to client
conn.send(data)
Client Side is set up like so:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
data = s.recv(2400000)
Then the data is just relayed back out for use with other applications via sock_sender.sendto(data, (SENDMCAST_GRP, SENDMCAST_PORT)).
I need to ensure the data between the client/server socket connection is accurate and complete.
Let me explain it a little bit. The video can be sent in the form of bytes with the aid of struct. It is part of the python standard library string services.
It interprets strings as packed binary data and performs conversions between Python values and C structs represented as Python strings. This is helpful handling binary data in files, socket network connections and other sources. In server.py, the frame matrix is pickled dump as a string in variable a and then used struct.pack to add a reference payloadsize (for the string in a). The payload_size is attached using + to the a and then .sendall sends the whole frame. To simply explain it, lets suppose our frame is just 3x3 matrix:
frame=np.array([[1,2,3],[4,5,6],[7,8,9]])
a = pickle.dumps(frame)
The pickled form of frame is shown below as a string:
b'\x80\x03cnumpy.core.multiarray\n_reconstruct\nq\x00cnumpy\nndarray\nq\
x01K\x00\x85q\x02C\x01bq\x03\x87q\x04Rq\x05(K\x01K\x03K\x03\x86q\x06cnumpy
\ndtype\nq\x07X\x02\x00\x00\x00i4q\x08K\x00K\x01\x87q\tRq\n(K\x03X\x01\x00
\x00\x00
Here payload_size: len(a) is 193 and its string representation in a 4 byte 'L' format is b'\xc1\x00\x00\x00'.
Then, message = struct.pack("L", len(a))+a
b'\xc1\x00\x00\x00\x80\x03cnumpy.core.multiarray\n_reconstruct\nq\x00cnumpy\nndarray\nq\
x01K\x00\x85q\x02C\x01bq\x03\x87q\x04Rq\x05(K\x01K\x03K\x03\x86q\x06cnumpy
\ndtype\nq\x07X\x02\x00\x00\x00i4q\x08K\x00K\x01\x87q\tRq\n(K\x03X\x01\x00
\x00\x00
And now the message also contains the payload_size infront of the data. The len(message) = 197.
In client.py the s.recv(4096) means at the most 4096 bytes will be received through a blocking call.
The data is appended to the string in 4096 bytes per packet. The rest of the part is quite obvious.
For reference working versions of server.py and client.py are below. First run the server.py and then in another command window run client.py. The transmitted and received frames will be displayed. You can increase the number of maximum bytes. I hope this solves your problem!
server.py
import socket,cv2,pickle
import struct
serversocket = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 9999
serversocket.bind((host, port))
serversocket.listen(5)
while True:
clientsocket,addr = serversocket.accept()
print("Got a connection from %s" % str(addr))
if clientsocket:
vid = cv2.VideoCapture(0)
while(vid.isOpened()):
img, frame = vid.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
print(frame)
a = pickle.dumps(frame)
message =struct.pack("L", len(a))+a
clientsocket.sendall(message)
cv2.imshow('Transmitted',frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
clientsocket.close()
client.py
import socket,cv2,pickle
import struct
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 9999
s.connect((host, port))
data = b""
payload_size = struct.calcsize("L")
while True:
while len(data) < payload_size:
packet= s.recv(4096)
if not packet: break
data += packet
packed_msg_size = data[:payload_size]
data = data[payload_size:]
msg_size = struct.unpack("L", packed_msg_size)[0]
while len(data) < msg_size:
data += s.recv(4096)
frame_data = data[:msg_size]
data = data[msg_size:]
frame=pickle.loads(frame_data)
cv2.imshow('Received',frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break
s.close()