I use a port in my python program and close it,now I want to use it again.Just that port not another port.
Is there any way to force OS to free port with python?
#!/usr/bin/python # This is server.py file
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12349
portt = 12341 # Reserve a port for your service.
s.bind((host, portt)) # Bind to the port
s.connect((host, port))
s.close
ss = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
ss.bind((host, portt))
s.close
but the output is:
Traceback (most recent call last):
File "client.py", line 17, in <module>
ss.bind((host, portt))
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
You'll never be able to force the OS (with any sort of reasonable effort) to release a socket.
Instead you just want to say you don't care with setsockopt
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
This means that the option takes place at the Socket Object Level SOCKET (as opposed to the TCP or something else) and you're setting the Socket Option REUSEADDR (you're telling the OS that it's OK, you really do want to listen here). And finally, you're turning the option on with 1, rather than off (with 0).
Related
I am trying to learn how to use sockets using this tutorial:
https://www.tutorialspoint.com/python/python_networking.htm
I have copied the code from the site into my directory and ran it exactly as was done in the tutorial but got errors. Here is the code from the tutorial.
#!/usr/bin/python # This is server.py file
import socket # Import socket module
s = socket.socket() # Create a socket object
host = 'localhost' # Get local machine name
port = 12345 # Reserve a port for your service.
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
while True:
c, addr = s.accept() # Establish connection with client.
print("asdf")
c.send('Thank you for connecting')
c.close() # Close the connection
and client.py
#!/usr/bin/python # This is client.py file
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12345 # Reserve a port for your service.
s.connect((host, port))
print s.recv(1024)
s.close # Close the socket when done
These are the console commands I ran:
python server.py &
python client.py
I got this errors after running the command:
Traceback (most recent call last):
File "client.py", line 9, in <module>
s.connect((host, port))
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/soc ket.py", line 228, in meth
return getattr(self._sock,name)(*args)
socket.gaierror: [Errno 8] nodename nor servname provided, or not known
In case this is helpful, the version of python I am using is Python 2.7.10 and I use a mac that is version 10.12.6
Thanks in advance
From the docs of socket.gethostname:
Return a string containing the hostname of the machine where the
Python interpreter is currently executing.
Note: gethostname() doesn’t always return the fully qualified domain
name; use getfqdn() for that.
The host IP is not the same as the hostname. You have a couple of options:
You can either manually assign host to 0.0.0.0 or localhost
You can also query socket.gethostbyname:
host = socket.gethostbyname(socket.gethostname()) # or socket.getfqdn() if the former doesn't work
I did some changes in your code. Here's the server.py
#!/usr/bin/python # This is server.py file
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12345 # Reserve a port for your service.
s.bind((host, port)) # Bind to the port
s.listen(5)
c,addr= s.accept()
print "Got connection from the ", addr
c.send('Thank you for connecting')
c.close() # Close the connection
Here's the client.py
#!/usr/bin/python # This is client.py file
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12345 # Reserve a port for your service.
s.connect((host, port))
msg = (s.recv(1024))
print msg
s.close # Close the socket when done
I hope it will help
I am following this example,
#!/usr/bin/python # This is server.py file
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12345 # Reserve a port for your service.
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
while True:
c, addr = s.accept() # Establish connection with client.
print 'Got connection from', addr
c.send('Thank you for connecting')
c.close() # Close the connection
and I am getting this error despite good network:
>>> s.bind((host, port))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Applications/anaconda/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.gaierror: [Errno 8] nodename nor servname provided, or not known
How can I fix this?
Let's take a look at the docs:
socket.gethostname()
Return a string containing the hostname of the
machine where the Python interpreter is currently executing.
If you want to know the current machine’s IP address, you may want to
use gethostbyname(gethostname()). This operation assumes that there is
a valid address-to-host mapping for the host, and the assumption does
not always hold.
Note: gethostname() doesn’t always return the fully qualified domain
name; use getfqdn() (see above).
I guess this is what's happening: bind is trying to establish IP address for the host, but it fails. Run host = socket.gethostbyname(socket.gethostname()) and instead of a valid IP address you'll most probably see the same error as when calling bind.
You say the returned hostname is valid, but you have to make sure it's recognised by the DNS responder. Does the resolution work when doing, for example, ping {hostname} from the command line?
Possible solutions would be:
Fix your local DNS resolution.
Use host = socket.getfqdn() (in case you were not getting the fully qualified name which then couldn't be resolved properly). Even if it works I think you should try and fix the local resolution.
Use empty host (host = ''), which on bind would mean "listen on all available interfaces". (This is the first example in the docs.)
I was trying to write a code where a client connects to server on a default port number, the server then sends another port number to the client. The client now connects to the new port number.
Client:
import socket
import sys
import os
import signal
import time
s = socket.socket()
s.connect(("127.0.0.1", 6667))
line = s.recv(1024)
if line.strip():
port = int(line)
s.close()
soc = socket.socket()
soc.connect(("127.0.0.1", port))
print soc.recv(1024)
soc.close()
else:
s.close()
Server:
import socket
import sys
import os
import signal
import time
port = 7777
s = socket.socket()
s.bind(("127.0.0.1", 6667))
s.listen(0)
sc, address = s.accept()
print address
sc.send(str(port))
sc.close()
s.close()
sock = socket.socket()
sock.bind(("127.0.0.1", port))
soc, addr = sock.accept()
print addr
soc.send("Success")
soc.close()
sock.close()
When I execute this code, I am getting following errors on client and server sides.
Server:
('127.0.0.1', 36282)
Traceback (most recent call last):
File "server.py", line 17, in <module>
soc, addr = sock.accept()
File "/usr/lib/python2.7/socket.py", line 202, in accept
sock, addr = self._sock.accept()
socket.error: [Errno 22] Invalid argument
Client:
Traceback (most recent call last):
File "client.py", line 13, in <module>
soc.connect(("127.0.0.1", port))
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 111] Connection refused
Can someone explain me the reason for these errors and provide a solution for these errors.
Before you can listen to a TCP/IP socket (a connection based streaming socket) you need to use bind to assign a socket (created with socket.socket()) . Then you need to do listen to prepare it for incoming connections and then finally you do accept on the prepared socket.
You appear to be missing sock.listen(0) after your call to sock.bind(("127.0.0.1", port)). The Python documentation is short on details but it does say this about TCP/IP:
Note that a server must perform the sequence socket(), bind(), listen(), accept() (possibly repeating the accept() to service more than one client), while a client only needs the sequence socket(), connect(). Also note that the server does not sendall()/recv() on the socket it is listening on but on the new socket returned by accept().
Python bases its socket module on a Berkeley Socket model. You can find some more detailed information on Berkeley Sockets at this link . In particular it says this about bind:
bind() assigns a socket to an address. When a socket is created using socket(), it is only given a protocol family, but not assigned an address. This association with an address must be performed with the bind() system call before the socket can accept connections to other hosts.
Also consider what would happen if your client gets sent a port number (and tries to connect) before the server starts listening for connections (on port 7777 in this case). Although not the cause of your problems, I wanted to point out the scenario for completeness. Something you may consider is not closing the port 6667 socket until after you have called listen on the port 7777 socket. After calling listen you can then close down the first socket. On the client after reading the port you can wait until the first connection (port 6667) is closed down by the server and then connect to port 7777.
I am attempting to write a very simple server in python.
import socket
import sys
# Create a TCP/IP socket to listen on
server = socket.socket(socket.SOL_SOCKET, socket.SOCK_STREAM)
# Prevent from 'address already in use' upon server restart
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Bind the socket to port 8081 on all interfaces
server_address = ('localhost', 8081)
print 'starting up on %s port %s' % server_address
server.bind(server_address)
I have read what I think to be correct documentation for the socket library, and it suggests that the server.bind() takes an argument of a tuple. However, I get this error:
starting up on localhost port 8081
Traceback (most recent call last):
File "pyserver.py", line 14, in <module>
server.bind(server_address)
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
TypeError: argument must be string or read-only character buffer, not tuple
I have changed the argument to only a string, as the error warning suggests, and I get a
[Errno 98] Address already in use
error. I thought that the 8th line was in place to prevent that. What is going on?
The first argument to the socket.socket should be address family:
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
^^^^^^^^^^^^^^
Except that, your code should work.
Reason of the error message: argument must be string ...
In Linux, the value of the socket.SOL_SOCKET is 1 which is equal to the value of socket.AF_UNIX. Unix domain socket (AF_UNIX) use path (string) as a address
>>> import socket
>>> socket.AF_UNIX
1
>>> socket.SOL_SOCKET
1
UPDATE
Regarding Already already in use error, see SO_REUSEADDR and AF_UNIX.
I have copied simple server/client python programs to test some socket communications.
If host is defined as 'localhost' or '', they work.
If I substitute the actual hostname in /etc/hosts, they fail with the socket.gaierror 2.
socket.gethostname() returns the correct value
as does 'hostname' on the command line.
Here is the server code that fails
#!/usr/bin/env python
"""
A simple echo server
"""
import socket
import sys
host = ''
port = 50000
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
print( " using host [%s] " % (host) )
s.bind((host,port))
s.listen(backlog)
while 1:
client, address = s.accept()
data = client.recv(size)
print( data )
if data:
client.send(data)
client.close()
and here is the client program
#!/usr/bin/env python
"""
A simple echo client
"""
import socket
host = 'localhost'
port = 50000
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
s.connect((host,port))
s.send('Hello, world')
data = s.recv(size)
s.close()
print( 'Received:', data )
This is the actual output from the server.py while using the gethostname() call.
using host [HP-linux]
Traceback (most recent call last):
File "server.py", line 18, in <module>
s.bind((host,port))
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.gaierror: [Errno -2] Name or service not known
Like I said, if I comment out the 'gethostname() calls, they work.
I have not been able to find any posts about gaierrors that have answers that work to solve this issue.
This running on SuSE Linux 13.1, and python2.7.
Thanks
This issue was resolved by adding an alias to the /etc/hosts file.
No rational answer as to why this would work.
Binding the server on hostname you're actualy binding it on local address, this is because normally there's a line in /etc/hosts like this 127.0.1.1 somehostname, this is to use lo iface instead of eth on the same machine for optimization reasons. If you want to accept connections from all interfaces use '0.0.0.0' instead.
I simply did these steps.
Ran command:
hostname
Say it returned me a value 'yourHostName'
Make an entry in your /etc/hosts file as follows.
127.0.0.1 yourHostName localhost
Reference for this information is : format of /etc/hosts file. Which you can see here.