How to close socket after python fail? - python

First, I encountered sockets in Python and faced this problem: when some error in my python code occurs, for example some syntax error before conn.close() on the second script start port is in use. The script already finished, but the socket is still open, kind of like busy socket.
Here is an error just for example:
web#web-X501A1 /var/www $ cd /home/web/www/public/py
web#web-X501A1 ~/www/public/py $ python sockets.py
connected: ('127.0.0.1', 47168)
Traceback (most recent call last):
File "sockets.py", line 164, in <module>
data = re.find('(<onvif>.*<\/onvif>)')
AttributeError: 'module' object has no attribute 'find'
web#web-X501A1 ~/www/public/py $ python sockets.py
Traceback (most recent call last):
File "sockets.py", line 154, in <module>
sock.bind(('', 9090))
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 98] Address already in use
web#web-X501A1 ~/www/public/py $ python sockets.py
Traceback (most recent call last):
File "sockets.py", line 154, in <module>
sock.bind(('', 9090))
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 98] Address already in use
Code:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('', 9090))
sock.listen(1)
conn, addr = sock.accept()
try:
print 'connected:', addr
buffer = ''
while True:
buffer += conn.recv(1024)
data = re.find('(<code>.*<\/code>)', buffer)
print data
exit();
if not data:
continue
conn.send(data.upper())
except Exception:
pass
finally:
conn.close()

Enclose the usage of the socket in a try/finally clause. Close the socket in the finally part. Perhaps handle the exception in an except part. Something similar to this:
try:
result = x / y
except ZeroDivisionError:
print "division by zero!"
else:
print "result is", result
finally:
print "executing finally clause"

The problem here is the dirty socket closing which occurs when the script crashes without the proper TCP connection shutdown sequence. Thankfully there's a simple solution which tells the kernel to ignore the fact the socket is already in use (the port it's bound to):
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
That's all, add that before the bind call and you're set. Debugging your other errors will be much simpler and less time consuming once that's done ;) See more in the docs https://docs.python.org/2/library/socket.html#socket.socket.setsockopt

If you use netstat -nutap you should notice that you connection seems like it's still up, on a state named TIME_WAIT.
That's part of TCP protocol, and according to wikipedia:
represents waiting for enough time to pass to be sure the remote TCP
received the acknowledgment of its connection termination request.
[According to RFC 793 a connection can stay in TIME-WAIT for a maximum
of four minutes known as a MSL (maximum segment lifetime).]
So, when you try to reconnect immediately to the same port, python complains that this port is still busy and cant be bound yet, saying:
socket.error: [Errno 98] Address already in use
See this old question, where it is asked how to avoid this waiting time.

Related

Receive data from a client/server doesn't work

I developed a small Python program which should receive and output data from another client or server. However, I get an error message which is unknown to me. Can anyone help me? Thanks a lot
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('192.168.1.34', 80))
from_server = client.recv(4096)
client.close()
print from_server
Error:
Traceback (most recent call last):
File "CallManager2.py", line 4, in <module>
client.connect(('192.168.1.34', 80))
File "/usr/lib/python2.7/socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 111] Connection refused
The error comes from inability for your program to reach the server or other client.
Check that there is something listening to incoming connexions on the address you want to connect to.
Then you can check that the address you want to connect to is on the same network as your program.

Why am I getting a "Connection refused" in python? Can't resolve using existing solutions

import ssl
import socket
port = 3001
while True:
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ssl_socket = ssl.wrap_socket(s, cert_reqs=ssl.CERT_REQUIRED, ca_certs='scert.pem')
ssl_socket.connect(('127.0.0.1', 3001))
ssl_socket.write(str(input("Enter two numbers to add:")).encode())
z = ssl_socket.recv(1024)
print(z.decode())
ssl_socket.close()
The error I'm getting is:
Traceback (most recent call last):
ssl_socket.connect(('127.0.0.1', 3001))
self._real_connect(addr, False)
socket.connect(self, addr)
File "/usr/lib/python2.7/socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
error: [Errno 111] Connection refused
I am confused as to what to do. Already tried the methods on the other thread on socket.

Connecting two server in socket

I am a newbie in socket programming but i have a trouble that i have two server started on my localhost on port 3500 and 5000.Now i want thatmy client fist connect to the port 3500 perform some operation and then disconnect from 3500 while server will be running only client wil disconnect from 3500 and the it will connect to port 5000 and agian perform some operations.
I am using the below code to do this but getting error:-
import socket
s=socket.socket()
s.connect(('127.0.0.1',3500))
print("connectd to 3500")
print("hello friends")
s.close()
print("disconnect from 3500")
s.connect(('127.0.0.1',5000))
print("connected to 5000")
s.close()
But it is not able to connect to the second connection i.e port 5000.It gets connected to port 3500 successfully but while connecting to 5000 it throws an error.
Please any one to short out my mistake
Error:-
File "C:\Users\Lal rishav\Desktop\HubPort\test.py", line 9, in <module>
s.connect(('127.0.0.1',5000))
File "C:\Python27\lib\socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
File "C:\Python27\lib\socket.py", line 174, in _dummy
raise error(EBADF, 'Bad file descriptor')
You cannot do any operations on a closed socket, create a new one instead.
s.close()
# the socket is closed, you can't use it anymore!
# get another one:
s2 = socket.socket()
s2.connect(('127.0.0.1',5000))
s2.close()
# now s2 is closed, you can't use it anymore!

Python sockets - WinError 10054

I'm trying to make a client and server where the client sends a string to the server and the server sends a response back.
This is the method on my client
def send(self):
s = socket.socket()
s.connect(("127.0.0.1", 5012))
message = bytes("Send!", "utf-8")
s.send(message)
data = s.recv(1024)
data = str(data, "utf-8")
print(data)
s.close()
this is a method in the server which waits for client messages.
def listener(self):
print("Startet")
s = socket.socket()
s.bind(("127.0.0.1", 5012))
s.listen(1)
while True:
c, addr = s.accept()
while True:
data = c.recv(1024)
data = str(data, "utf-8")
print(data)
c.send(bytes("OK", "utf-8"))
c.close()
Running this I get:
Startet
Send!
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Anaconda3\lib\threading.py", line 914, in _bootstrap_inner
self.run()
File "C:\Anaconda3\lib\threading.py", line 862, in run
self._target(*self._args, **self._kwargs)
File "C:\workspace\Server.py", line 41, in listener
data = c.recv(1024)
ConnectionAbortedError: [WinError 10053]
An established connection was disconnected by the software on the hostcomputer
It prints out the Send!, so at least it recieves the messages, but then abruptly stops. The server should be able to run at all times, and take an
arbitrary amount of messages from the clients send function.
The client does a send() and then immediately a recv() without checking if data is available (e.g. using accept()). If the socket is non-blocking the recv() immediately returns (or it excepts for some other reason). An empty string is printed and the socket is closed. That's why the server gives an ConnectionAbortedError, the client has already closed the connection. Check this by adding a try/except around the client recv().

Python : file transfer giving errors

I am trying to send a file from a server to client but get errors. Please let me know where I am doing wrong.
This is my server code:
if msg in data.keys():
print("Requested file exists", msg)
f=open(msg,"rb")
datam= f.read(1024)
while (datam):
if(s.send(datam)):
print "sending data"
datam = f.read(1024)
s.close()
f.close
else:
print("File Not found",msg)
print("File Not found",data.keys())
c.close() # Close the connection
where msg contains the path address where file exists
c=client socket s=server socket
I want to read that file and send it to client but I get this error
Got connection from ('127.0.0.1', 42330)
('Requested file exists', '/home/beenish/Pictures/pew.txt')
Traceback (most recent call last):
File "server.py", line 41, in <module>
if(s.send(datam)):
socket.error: [Errno 32] Broken pipe
On client side, I have written this code to recieve that file
s.listen(15)
f = open('\home\beenish\pictures\lol.txt', 'wb')
data = s.recv(1024)
while(data):
f.write(data)
data=s.recv(1024)
f.close()
s.close # Close the socket when done
where s is the client socket
Here I get this error
Traceback (most recent call last):
File "client.py", line 26, in <module>
s.listen(15)
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 22] Invalid argument
On the client side you have an error on this line:
s.listen(15)
And the Python docs say that the argument has a system dependant maximum, usually 5. So try finding out the maximum for your system of just use a lower value and see what happen.
The server side error could be a side effect of the client side failure.
That is the kind of error you get when you call socket.listen before calling socket.bind. Keep in mind that a server always has to follow the sequence socket(), bind(), listen() and accept() in that specific order.

Categories