I was trying to understand how non-blocking sockets work ,so I wrote this simple server in python .
import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1',1000))
s.listen(5)
s.setblocking(0)
while True:
try:
conn, addr = s.accept()
print ('connection from',addr)
data=conn.recv(100)
print ('recived: ',data,len(data))
except:
pass
Then I tried to connect to this server from multiple instances of this client
import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1',1000))
while True:
continue
But for some reason putting blocking to 0 or 1 dose not seem to have an effect and server's recv method always block the execution.
So, dose creating non-blocking socket in python require more than just setting the blocking flag to 0.
setblocking only affects the socket you use it on. So you have to add conn.setblocking(0) to see an effect: The recv will then return immediately if there is no data available.
You just need to call setblocking(0) on the connected socket, i.e. conn.
import socket
s = socket.socket()
s.bind(('127.0.0.1', 12345))
s.listen(5)
s.setblocking(0)
>>> conn, addr = s.accept()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.7/socket.py", line 202, in accept
sock, addr = self._sock.accept()
socket.error: [Errno 11] Resource temporarily unavailable
# start your client...
>>> conn, addr = s.accept()
>>> conn.recv() # this will hang until the client sends some data....
'hi there\n'
>>> conn.setblocking(0) # set non-blocking on the connected socket "conn"
>>> conn.recv()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
socket.error: [Errno 11] Resource temporarily unavailable
https://docs.python.org/3/library/socket.html#socket.setdefaulttimeout
You can use s.setdefaulttimeout(1.0) to apply all connection sockets as default.
Related
I have a very simple Python code for bind or connect to a port. it works without any error on Ubuntu and CentOs but I have an error on Windows 10. I turned off the firewall and antivirus but it didn't help.
my code:
import socket
port = 9999
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
try:
s.connect((host,port))
except:
s.bind((host, port))
s.listen(1)
print("I'm a server")
clientsocket, address = s.accept()
else:
print("I'm a client")
error on windows 10:
Traceback (most recent call last):
File "win.py", line 11, in <module>
s.connect((host,port))
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
During the handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "win.py", line 13, in <module>
s.bind((host, port))
OSError: [WinError 10022] An invalid argument was supplied
Edit:
I found my problem is in Try... Except part, if I put this code in two files my problem will solve. But Why? try except don't work correctly in Windows?
The connect() fails because there is no server socket listening at (host,port).
The bind() fails because you can't bind to a hostname, only to an IP address. Unless you want to listen on just a specific network interface, you should bind to 0.0.0.0 to listen on all interfaces.
I am doing a course and it is teaching me socket right now but this code they are showing is not working for me?
import socket
def main():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "localhost"
port = 5000
s.connect((host, port))
print("It works!")
if __name__ == "__main__":
main()
Error:
Traceback (most recent call last):
File "create_connection.py", line 14, in <module>
main()
File "create_connection.py", line 9, in main
s.connect((host, port))
ConnectionRefusedError: [Errno 111] Connection refused
EDIT:
On this video there is nothing listening but there is no error?
Connect request failed with connection refused.
You need a TCP server which is listening on 5000 port.
There should be a server waiting for connection in port 5000, only then it will work. Otherwise this error is expected
I've written a python script that will communicate with a server, get its data and will send the data back to the server, some sort of an "echo client".
This is what I've written:
import socket
import time
def netcat(hostname, port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((hostname, port))
s.shutdown(socket.SHUT_WR)
while 1:
data = s.recv(1024)
if data == "":
break
print "Received:", repr(data)
data = data.replace("\n", "")
time.sleep(1)
s.sendall(data)
print "Sent:", data
print "Connection closed."
s.close()
netcat("127.0.0.1", 4444)
I get this output:
Received: 'Welcome!\n'
And after that, I get this error:
Traceback (most recent call last):
File "client.py", line 22, in <module>
netcat("127.0.0.1", 4444)
File "client.py", line 17, in netcat
s.sendall(data)
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 32] Broken pipe
I've looked already for a solution for this error online, but with no luck.
Can someone please help me figure it out?
Thank you
I've been working on sockets a lot lately. I don't have a server right now to test your code so I thought I would quickly comment on what I see. You seem to be shutting down the socket (for writing) at the beginning, so your receive statement worked, but your sendall statement fails.
def netcat(hostname, port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((hostname, port))
s.shutdown(socket.SHUT_WR) <-- WHY IS THIS HERE?
I've been programming my chat but then I get an error which crashes the server and so then the next time I won't be able to use the same port and so I get socket.bind error when I run it again. How to fix?
Source code:
import socket
from threading import Thread
def clientHandler():
conn, addr = sock.accept()
print addr, "is Connected"
while 1:
data = conn.recv(1024)
if not data:
break
print "Received Message", repr(data)
HOST = ''
PORT = raw_input('PORT: ')
PORT = int(PORT)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(5)
print "Server is running......"
#Thread(target=clientHandler).start()
#Thread(target=clientHandler).start()
#Thread(target=clientHandler).start()
for i in range(5):
Thread(target=clientHandler).start()
sock.close()
This is what happens:
Server is running......
Exception in thread Thread-5:
Traceback (most recent call last):
File "C:\Python27\lib\threading.py", line 810, in __bootstrap_inner
self.run()
File "C:\Python27\lib\threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "C:/Users/Judicaƫl/Desktop/server_test.py", line 5, in clientHandler
conn, addr = sock.accept()
File "C:\Python27\lib\socket.py", line 202, in accept
sock, addr = self._sock.accept()
File "C:\Python27\lib\socket.py", line 170, in _dummy
raise error(EBADF, 'Bad file descriptor')
error: [Errno 9] Bad file descriptor
>>> ==================================================== RESTART ====================================================
>>>
Traceback (most recent call last):
File "C:/Users/Judicaƫl/Desktop/server_test.py", line 15, in <module>
sock.bind((HOST, PORT))
File "C:\Python27\lib\socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
error: [Errno 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted
I am using Win7 64bit python 2.7.6 64bit version
and is there also a way to restore the ports which had been blocked or does it auto restore when restart comp?
*******FIXED by Daniel************
Fixed Code:
import socket, sys
from threading import Thread
def clientHandler(conn, addr):
print addr, "is Connected"
while 1:
data = conn.recv(1024)
if data == 'Admin: /server shutdown':
sock.close()
print 'quitting...'
quit()
if not data:
break
conn.sendall(data) # only sends to original sender
print "Received Message", repr(data)
HOST = ''
PORT = int(raw_input('PORT: '))
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(999999)
print "Server is running......"
#Thread(target=clientHandler).start()
#Thread(target=clientHandler).start()
#Thread(target=clientHandler).start()
for i in range(999999):
conn, addr = sock.accept()
Thread(target=clientHandler, args=(conn, addr)).start()
sock.close()
How do I now send the messages received to all clients?
The functions you have to call at server side is the following:
- create a socket
- bind it to a port
- listen
- accept
- handle the client communication
You have multiple threads for accept. Then you close the socket, so all accepts fail.
The correct way is
while True:
client, addr = sock.accept()
Thread(target=clientHandler, args=(client, addr)).start()
The following code runs a socket server on a thread. The client socket sends 'client: hello' to the server, and the server socket receives and replies 'server: world'.
import socket
import threading
def server():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1', 12345))
sock.listen(1)
req, addr = sock.accept()
print req.recv(1024)
req.sendall('server: world')
def client():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('127.0.0.1', 12345))
sock.sendall('client: hello')
print sock.recv(1024)
def main():
t = threading.Thread(target=server)
t.start()
client()
if __name__ == '__main__':
main()
It runs ok as expected the first time, but from the second time, if you do not wait for a good few seconds for the server to release the socket, and if you try this on a Linux machine or Mac (Windows do not get it somehow) you will run into this error:
Traceback (most recent call last):
File "socket_send_receive.py", line 24, in <module>
main()
File "socket_send_receive.py", line 21, in main
client()
File "socket_send_receive.py", line 14, in client
sock.connect(('127.0.0.1', 12345))
File "<string>", line 1, in connect
socket.error: [Errno 111] Connection refused
Exception in thread Thread-1:
Traceback (most recent call last):
File "/home/cxuan/python/2.6/lib/python2.6/threading.py", line 532, in __bootstrap_inner
self.run()
File "/home/cxuan/python/2.6/lib/python2.6/threading.py", line 484, in run
self.__target(*self.__args, **self.__kwargs)
File "socket_send_receive.py", line 6, in server
sock.bind(('127.0.0.1', 12345))
File "<string>", line 1, in bind
error: [Errno 98] Address already in use
I am looking for some insight into why this is happening and if it is possible to be genuinely resolved or what best practice should be adopted.
I know already using this option can be a workaround thanks to the other posts here on stackoverflow.
socket.SO_REUSEADDR
When a socket is closed, it ends up in a state called STATE_WAIT (see this diagram). While the socket is in this state, no one else can use the same address (ip-number/port pair) unless the SO_REUSEADDR option is set on the socket.
See e.g. the Wikipedia article on TCP for more information about how TCP works and the different states.