I am using Python version 2.7. I would like to send data via UDP client. However, when i go to the line my the sending of sata is too slow.
Could you help me to accelerate my program? I am a beginner in network using Python.
Thank you in advance
Here is my script.
import socket
import time
UDP_IP = "127.0.0.1"
UDP_PORT = 5001
BUFFER_SIZE = 512
MESSAGE = " $POS,Target,1418345.36,4188240.67,14.16,350\r"
print "UDP target IP:", UDP_IP
print "UDP target port:", UDP_PORT
print "message:", MESSAGE
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
while 1:
print "send"
sock.sendto(MESSAGE, (UDP_IP,UDP_PORT))
#time.sleep(0.05)
Odds are the slowest part of your loop is print statement. It is usual for some IDEs and consoles.
while 1:
print "send"
sock.sendto(MESSAGE, (UDP_IP,UDP_PORT))
Remove print "send" and see if it helps.
Related
I'am trying to do an integration via HTTP socket. I'am using python to create the socket client and send data to a socket server created in C.
As you can see in the following images, the integration documentation gives an example in C that shows how I must send the data to the server:
Integration documentation example:
1- define record / structure types for the message header and for each message format
2- Declare / Create a client socket object
3- Open the socket component in non blocking mode
4- declare a variable of the data structure type relevant to the API function you wish to call – then fill it with the correct data (including header). Copy the structure data to a byte array and send it through the socket
I've tried to do that using the ctypes module from python:
class SPMSifHdr(ctypes.Structure):
_fields_ = [
('ui32Synch1', ctypes.c_uint32),
('ui32Synch2', ctypes.c_uint32),
('ui16Version', ctypes.c_uint16),
('ui32Cmd', ctypes.c_uint32),
('ui32BodySize', ctypes.c_uint32)
]
class SPMSifRegisterMsg(ctypes.Structure):
_fields_ = [
('hdr1', SPMSifHdr),
('szLisence', ctypes.c_char*20),
('szApplName', ctypes.c_char*20),
('nRet', ctypes.c_int)
]
body_len = ctypes.sizeof(SPMSifRegisterMsg)
header = SPMSifHdr(ui32Synch1=0x55555555, ui32Synch2=0xaaaaaaaa, ui16Version=1, ui32Cmd=1, ui32BodySize=body_len)
body = SPMSifRegisterMsg(hdr1=header, szLisence='12345', szApplName='MyPmsTest', nRet=1)
socket_connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# config is a dict with the socket server connection params
socket_connection.connect((config.get('ip'), int(config.get('port'))))
socket_connection.sendall(bytearray(body))
socket_connection.recv(1024)
When I call the socket recv function it never receive anything, so I have used a windows tool to check the data that I sent and as you can see in the next image it seems any data is sent:
Socket sniff
I've tried to send even a simple "Hello! world" string and the result is always the same.
The socket connection is open. I know it because I can see how many connections are open from the server panel.
What am I doing wrong?
The error was that the SocketSniff program only shows the sent data if the server return a response. In it case the server did never return nothing because some bytes were missing.
I found it creating my own socket echo server and checking that the data I was sending were uncomplete.
Mystery solved. :D
Whenever I send a message from my client to the server (or vice versa), I have to wait until I've sent a message from the other side for it to register.
server.py
from socket import *
host = '127.0.0.1'
port = 80
s = socket(AF_INET, SOCK_STREAM)
s.connect((host, port))
while True:
message = raw_input("Send message: ")
s.send(message)
print s.recv(1024)
client.py
from socket import *
host = '127.0.0.1'
port = 80
s = socket(AF_INET, SOCK_STREAM)
s.bind((host, port))
s.listen(5)
c,addr = s.accept()
while True:
message = raw_input("Send message: ")
c.send(message)
print c.recv(1024)
Example:
server sends message
nothing happens on client side
client sends message
both server and client receive their messages
this will happen over and over
Well, it's obvious that you have to wait for "the other side" because you have raw_input calls sitting in your code that are waiting for the user to type something...
That said, you're also recv'ing 1024 bytes but sending much less, probably. Thus the recv() will usually hang until it has enough data (but not always, in which case it returns less). Remember that with lowlevel socket communication you have to properly take care of message sizes/boundaries yourself!
You can agree on a termination byte such as "\n" that signifies the boundary between messages, or another strategy is to prepend every message by a few bytes that signify the size of the message following it. You then recv() exactly that amount. Or just send a fixed amount of data for every message.
What remains is that you still have to deal with the fact that send() and recv() sometimes don't send or receive everything: they have a return value that is important. Using sendall, and recv with the MSG_WAITALL flag can take care of most issues, but there's no guarantee.
Read this https://docs.python.org/3/howto/sockets.html#using-a-socket for starters.
I recently encountered ZeroMQ ( pyzmq ) and I found this very useful piece of code on a website Client Server with REQ and REP and I modified it to make only a single process call. My code is:
import zmq
import sys
from multiprocessing import Process
port = 5556
def server():
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://*:%s" % port)
print "Running server on port: %s" % port
# serves only 5 request and dies
#for reqnum in range(4):
# Wait for next request from client
message = socket.recv()
print "Received request : %s from client" % message
socket.send("ACK from %s" % port)
def client():
context = zmq.Context()
socket = context.socket(zmq.REQ)
#for port in ports:
socket.connect ("tcp://localhost:%s" % port)
#for request in range(20):
print "client Sending request to server"
socket.send ("Hello")
message = socket.recv()
print "Received ACK from server""[", message, "]"
time.sleep (1)
if __name__ == "__main__":
Process(target=server, args=()).start()
Process(target=client, args=()).start()
time.sleep(1)
I realise that ZeroMQ is powerful, especially with multiprocessing/Multi-threading calls, but I was wondering if it is possible to call the server and client methods without calling them as a Process in __main__. For example, I tried calling them like:
if __name__ == "__main__":
server()
client()
For some reason the server started but not the client and I had to hard exit the program.
Is there any way to achieve this without Process calling? If not, then is there a socket program ( with or without a client server type architecture ) that functions exactly like the one above? ( I want a single program, not 2 programs running in different terminals as a classic CL-SE program ).
Using Ubuntu 14.04, 32-bit VM with Python-2.7
Simply, the server() processing had to start, not the client()
Why?
because the pure [SERIAL]-process scheduling has stepped into the server() code, where a Context instance has been instantiated, a Socket-instance was created, and next, the call to a socket.recv() method has hung-up the whole process into an unlimited & uncontrollable waiting state, expecting to receive some message, having the REP-LY Formal Behaviour Pattern ready on the local-side, but having no live counterparty, that would have sent any such expected message yet.
Yes, distributed-computing has several new dimensions ( degrees-of-freedom ) to care about -- the elementary (non)-presence and order of events being just recognised in this trivial scenario.
Wherever I can advocate, I do, NEVER use a blocking format of .recv() + read about a risk of a principally un-salvageable REQ/REP mutual dead-lock ( you have no doubt when it will happen, but have a certainty, it will & a certainty, you cannot salvage the mutually dead-locked counterparties, once it happens )
So, welcome into the realms of a distributed-processing reality
I am having an issue trying to communicate between a python TCP server and a c++ TCP client.
After the first call, which works fine, the subsequent calls cause issues.
As far as WinSock is concerned, the send() function worked properly, it returns the proper length and WSAGetLastError() does not return anything of significance.
However, when watching the packets using wireshark, i notice that the first call sends two packets, a PSH,ACK with all of the data in it, and an ACK right after, but the subsequent calls, which don't work, only send the PSH,ACK packet, and not a subsequent ACK packet
the receiving computers wireshark corroborates this, and the python server does nothing, it doesnt have any data coming out of the socket, and i cannot debug deeper, since socket is a native class
when i run a c++ client and a c++ server (a hacked replica of what the python one would do), the client faithfully sends both the PSH,ACk and ACK packets the whole time, even after the first call.
Is the winsock send function supposed to always send a PSH,ACK and an ACK?
If so, why would it do so when connected to my C++ server and not the python server?
Has anyone had any issues similar to this?
client sends a PSH,ACK and then the
server sends a PSH,ACK and a
FIN,PSH,ACK
There is a FIN, so could it be that the Python version of your server is closing the connection immediately after the initial read?
If you are not explicitly closing the server's socket, it's probable that the server's remote socket variable is going out of scope, thus closing it (and that this bug is not present in your C++ version)?
Assuming that this is the case, I can cause a very similar TCP sequence with this code for the server:
# server.py
import socket
from time import sleep
def f(s):
r,a = s.accept()
print r.recv(100)
s = socket.socket()
s.bind(('localhost',1234))
s.listen(1)
f(s)
# wait around a bit for the client to send it's second packet
sleep(10)
and this for the client:
# client.py
import socket
from time import sleep
s = socket.socket()
s.connect(('localhost',1234))
s.send('hello 1')
# wait around for a while so that the socket in server.py goes out of scope
sleep(5)
s.send('hello 2')
Start your packet sniffer, then run server.py and then, client.py. Here is the outout of tcpdump -A -i lo, which matches your observations:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 96 bytes
12:42:37.683710 IP localhost:33491 > localhost.1234: S 1129726741:1129726741(0) win 32792 <mss 16396,sackOK,timestamp 640881101 0,nop,wscale 7>
E..<R.#.#...............CVC.........I|....#....
&3..........
12:42:37.684049 IP localhost.1234 > localhost:33491: S 1128039653:1128039653(0) ack 1129726742 win 32768 <mss 16396,sackOK,timestamp 640881101 640881101,nop,wscale 7>
E..<..#.#.<.............C<..CVC.....Ia....#....
&3..&3......
12:42:37.684087 IP localhost:33491 > localhost.1234: . ack 1 win 257 <nop,nop,timestamp 640881102 640881101>
E..4R.#.#...............CVC.C<......1......
&3..&3..
12:42:37.684220 IP localhost:33491 > localhost.1234: P 1:8(7) ack 1 win 257 <nop,nop,timestamp 640881102 640881101>
E..;R.#.#...............CVC.C<......./.....
&3..&3..hello 1
12:42:37.684271 IP localhost.1234 > localhost:33491: . ack 8 win 256 <nop,nop,timestamp 640881102 640881102>
E..4.(#.#...............C<..CVC.....1}.....
&3..&3..
12:42:37.684755 IP localhost.1234 > localhost:33491: F 1:1(0) ack 8 win 256 <nop,nop,timestamp 640881103 640881102>
E..4.)#.#...............C<..CVC.....1{.....
&3..&3..
12:42:37.685639 IP localhost:33491 > localhost.1234: . ack 2 win 257 <nop,nop,timestamp 640881104 640881103>
E..4R.#.#...............CVC.C<......1x.....
&3..&3..
12:42:42.683367 IP localhost:33491 > localhost.1234: P 8:15(7) ack 2 win 257 <nop,nop,timestamp 640886103 640881103>
E..;R.#.#...............CVC.C<......./.....
&3%W&3..hello 2
12:42:42.683401 IP localhost.1234 > localhost:33491: R 1128039655:1128039655(0) win 0
E..(..#.#.<.............C<......P...b...
9 packets captured
27 packets received by filter
0 packets dropped by kernel
What size of packets do you send?
If they are small - may be Nagle's Algorith & Delayed ACK Algorithm is your headache? From what you described think Delayed ACK is involved...
I am writing an XMLRPC client in c++ that is intended to talk to a python XMLRPC server.
Unfortunately, at this time, the python XMLRPC server is only capable of fielding one request on a connection, then it shuts down, I discovered this thanks to mhawke's response to my previous query about a related subject
Because of this, I have to create a new socket connection to my python server every time I want to make an XMLRPC request. This means the creation and deletion of a lot of sockets. Everything works fine, until I approach ~4000 requests. At this point I get socket error 10048, Socket in use.
I've tried sleeping the thread to let winsock fix its file descriptors, a trick that worked when a python client of mine had an identical issue, to no avail.
I've tried the following
int err = setsockopt(s_,SOL_SOCKET,SO_REUSEADDR,(char*)TRUE,sizeof(BOOL));
with no success.
I'm using winsock 2.0, so WSADATA::iMaxSockets shouldn't come into play, and either way, I checked and its set to 0 (I assume that means infinity)
4000 requests doesn't seem like an outlandish number of requests to make during the run of an application. Is there some way to use SO_KEEPALIVE on the client side while the server continually closes and reopens?
Am I totally missing something?
The problem is being caused by sockets hanging around in the TIME_WAIT state which is entered once you close the client's socket. By default the socket will remain in this state for 4 minutes before it is available for reuse. Your client (possibly helped by other processes) is consuming them all within a 4 minute period. See this answer for a good explanation and a possible non-code solution.
Windows dynamically allocates port numbers in the range 1024-5000 (3977 ports) when you do not explicitly bind the socket address. This Python code demonstrates the problem:
import socket
sockets = []
while True:
s = socket.socket()
s.connect(('some_host', 80))
sockets.append(s.getsockname())
s.close()
print len(sockets)
sockets.sort()
print "Lowest port: ", sockets[0][1], " Highest port: ", sockets[-1][1]
# on Windows you should see something like this...
3960
Lowest port: 1025 Highest port: 5000
If you try to run this immeditaely again, it should fail very quickly since all dynamic ports are in the TIME_WAIT state.
There are a few ways around this:
Manage your own port assignments and
use bind() to explicitly bind your
client socket to a specific port
that you increment each time your
create a socket. You'll still have
to handle the case where a port is
already in use, but you will not be
limited to dynamic ports. e.g.
port = 5000
while True:
s = socket.socket()
s.bind(('your_host', port))
s.connect(('some_host', 80))
s.close()
port += 1
Fiddle with the SO_LINGER socket
option. I have found that this
sometimes works in Windows (although
not exactly sure why):
s.setsockopt(socket.SOL_SOCKET,
socket.SO_LINGER, 1)
I don't know if this will help in
your particular application,
however, it is possible to send
multiple XMLRPC requests over the
same connection using the
multicall method. Basically
this allows you to accumulate
several requests and then send them
all at once. You will not get any
responses until you actually send
the accumulated requests, so you can
essentially think of this as batch
processing - does this fit in with
your application design?
Update:
I tossed this into the code and it seems to be working now.
if(::connect(s_, (sockaddr *) &addr, sizeof(sockaddr)))
{
int err = WSAGetLastError();
if(err == 10048) //if socket in user error, force kill and reopen socket
{
closesocket(s_);
WSACleanup();
WSADATA info;
WSAStartup(MAKEWORD(2,0), &info);
s_ = socket(AF_INET,SOCK_STREAM,0);
setsockopt(s_,SOL_SOCKET,SO_REUSEADDR,(char*)&x,sizeof(BOOL));
}
}
Basically, if you encounter the 10048 error (socket in use), you can simply close the socket, call cleanup, and restart WSA, the reset the socket and its sockopt
(the last sockopt may not be necessary)
i must have been missing the WSACleanup/WSAStartup calls before, because closesocket() and socket() were definitely being called
this error only occurs once every 4000ish calls.
I am curious as to why this may be, even though this seems to fix it.
If anyone has any input on the subject i would be very curious to hear it
Do you close the sockets after using it?