I am doing asynchronous networking programming with tornado, I've created a socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM))
and put it in tornado iostream
iostream = tornado.iostream.IOStream(sock)
I wonder if I could set the socket 'keepalive' after then? Is the setting still valid after the iostream creation. Thank you in advance.
I would say it's usually best to set any socket options you want before creating the IOStream, but in most cases it's fine to set it afterwards as well (as long as the underlying socket option can be set on a socket that is already connected). As of Tornado 4.0 the only option IOStream touches directly is TCP_NODELAY.
Related
I am implementing a socket in Python to pass data back and forth between two scripts running on the same machine as part of a single Tkinter application.
This data, in many cases, will be highly sensitive (i.e. personal credit card numbers).
Does passing the data between scripts in this way open me up to any security concerns?
Server side:
import socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(('localhost', 8089))
serversocket.listen(5) # become a server socket, maximum 5 connections
while True:
connection, address = serversocket.accept()
buf = connection.recv(64)
if len(buf) > 0:
print buf
break
Client side:
import socket
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect(('localhost', 8089))
clientsocket.send('hello')
Code source.
Additional considerations:
This will only ever function as part of a single Tkinter application, on a single machine. Localhost will always be specified.
I am unable to use multiprocessing or threading; please no suggestions for using one of those or an alternative, other than varieties of socket. For more info as to why, see this SO question, answers, and comments. It has to do with this needing to function on Windows 7 and *nix, as well as my desired set-up.
Yes, passing the data between scripts in this way may raise a security concerns. If the attacker has an access to the same machine - he can easily sniff the traffic using the tool like tcpdump for example.
To avoid this you should encrypted your traffic - I have posted a comment below your question with an example solution.
How to create multi-server sockets on one client in Python ?
I am thinking about create a List of server socket and make the connection with
non-blocking socket, but i don't find a good tutorial for that, thats why i came here,
to ask for better solution or a guide for non-blocking socket.
Thank you !
Thank for the help, but i mean to something different, i have list of Servers Ip like that:
SERVER_IP = ['127.0.0.1', '127.0.0.2', '127.0.0.3', '127.0.0.4', '127.0.0.5', '127.0.0.6, '127.0.0.7']
I have one option to create a list of sockets by ip, and try to connect to every Ip Server, but i ask
here if i have a different way to connect to all this Servers Ip without a list of sockets, something more convenient.
Thank you.
If you want to have multiple sockets connected to multiple servers, you should check out the select module (http://docs.python.org/2/library/select.html).
Basically, it works like this:
import socket, select
socks = {}
# Connect to different servers here #
sock1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socks[sock1.fileno()] = sock1
poll = select.poll()
for sock in socks:
poll.register(sock)
while 1:
fd, event = poll.poll() # Optional timeout parameter in seconds
sock = socks[fd]
sock.recv(1024) # Do stuff
A note, the poll.poll() method returns the underlying file number (what your operating system uses to represent files) which is useless to you. I just stores the sockets in a dictionary by that number so you could get the actual socket object from the filenumber that is given by poll. I recommend reading the documentation for select.poll, the link above.
You can use select.
http://pymotw.com/2/select/ plus the select documentation.
Or some third party module such as twisted.
I created a program which listens to particular socket in python, however I ctrl+c'd script which resulted in .close() nor called, however how can I free the socket now.
The socket is closed when the process exits. The port it was using may hang around for a couple of minutes, that's normal, then it will disappear. If you need to re-use the port immediately, set SO_REUSEADDR before binding or connecting.
Set the SO_REUSEADDR socket option before calling the bind method, like this:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
That will instruct the socket to freely reuse the ports left in a waiting state by recent runs of the program.
Or, use the SocketServer.TCPServer class from the standard library, which will automatically do this if you set the allow_reuse_address property on the server instance to a true value.
I have a Python application which opens a simple TCP socket to communicate with another Python application on a separate host. Sometimes the program will either error or I will directly kill it, and in either case the socket may be left open for some unknown time.
The next time I go to run the program I get this error:
socket.error: [Errno 98] Address already in use
Now the program always tries to use the same port, so it appears as though it is still open. I checked and am quite sure the program isn't running in the background and yet my address is still in use.
SO, how can I manually (or otherwise) close a socket/address so that my program can immediately re-use it?
Update
Based on Mike's answer I checked out the socket(7) page and looked at SO_REUSEADDR:
SO_REUSEADDR
Indicates that the rules used in validating addresses supplied in a bind(2) call should
allow reuse of local addresses. For AF_INET sockets this means that a socket may bind,
except when there is an active listening socket bound to the address. When the listenā
ing socket is bound to INADDR_ANY with a specific port then it is not possible to bind
to this port for any local address. Argument is an integer boolean flag.
Assume your socket is named s... you need to set socket.SO_REUSEADDR on the server's socket before binding to an interface... this will allow you to immediately restart a TCP server...
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((ADDR, PORT))
You might want to try using Twisted for your networking. Mike gave the correct low-level answer, SO_REUSEADDR, but he didn't mention that this isn't a very good option to set on Windows. This is the sort of thing that Twisted takes care of for you automatically. There are many, many other examples of this kind of boring low-level detail that you have to pay attention to when using the socket module directly but which you can forget about if you use a higher level library like Twisted.
You are confusing sockets, connections, and ports. Sockets are endpoints of connections, which in turn are 5-tuples {protocol, local-ip, local-port, remote-ip, remote-port}. The killed program's socket has been closed by the OS, and ditto the connection. The only relic of the connection is the peer's socket and the corresponding port at the peer host. So what you should really be asking about is how to reuse the local port. To which the answer is SO_REUSEADDR as per the other answers.
I want to open a TCP client socket in Python. Do I have to go through all the low-level BSD create-socket-handle / connect-socket stuff or is there a simpler one-line way?
Opening sockets in python is pretty simple. You really just need something like this:
import socket
sock = socket.socket()
sock.connect((address, port))
and then you can send() and recv() like any other socket
OK, this code worked
s = socket.socket()
s.connect((ip,port))
s.send("my request\r")
print s.recv(256)
s.close()
It was quite difficult to work that out from the Python socket module documentation. So I'll accept The.Anti.9's answer.
For developing portable network programs of any sort in Python, Twisted is quite useful. One of its benefits is providing a convenient layer above low-level socket APIs.