Simple TCP EchoServer in Python - python

I found this script of TCP server which "echoes" back the data to the client.
#!/usr/bin/env python
import socket
host = ''
port = 50000
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
while 1:
client, address = s.accept()
data = client.recv(size)
if data:
client.send(data)
client.close()
I'm trying to test & understand it before I will be able to do something on my own and modify, but I'm having some problems. When I'm trying to run the .py script I get the following error in my Terminal (using Ubuntu 14.04 LTS)
> Traceback (most recent call last):
File "echo.py", line 14, in <module>
s.bind((host,port))
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
My Python version is 2.7.6
is there something wrong with the code or I'm doing something wrong?
UPDATE:
it gets worse, any script I run with bind(host, port) gives me the same error.
any help would be appreciated

Perhaps you accidentally ran the EchoServer twice in different windows? You can only bind one receiver to a port/address combination.

Seems like there is some other application running on those ports.
Can you try checking if there are any other app listening on same port using:
netstat -ntlpu | grep 50000

To bind a server it's a little confusing but you have to use a tuple. The correct way is server.bind((host, port))

Related

Why doesn't the Python socket receive packets?

My program doesn't receive any packets (on UDP, Windows 10), but when I sniff the data on Wireshark I can see that the data is indeed sent. I know that it doesn't have anything to do with my local network because when I switch to a hotspot it still doesn't work.
Another thing is that the program receives the data for my friends who work with me on the same project, but for me, even if I'm using the same computer for the client and server it doesn't work.
I even tried to enable Promiscuous in the program via the os module after binding the socket by adding these lines:
if os.name == “nt”:
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
but all I got was
Traceback (most recent call last):
File "C:/Users/roeym/PycharmProjects/client game/tank_trouble_dynamic_map.py", line 5, in <module>
import tank_client
File "C:\Users\roeym\PycharmProjects\client game\tank_client.py", line 13, in <module>
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
OSError: [WinError 10022] An invalid argument was supplied
Can you please help me figure out why my program doesn't receive the data?
This is how I set the socket up:
ip = socket.gethostbyname(socket.gethostname())
port = 8888
s = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
s.bind((ip, port))
print(f"[!][!] Server is up, running on {ip}, port- {port} [!][!]")
and this is how I receive packets:
while run:
data, ip = s.recvfrom(bufferSize)
data = str(data)
data = data[2:]
data = data[:-1]
if data == "":
continue
print(data)

Broken pipe error when trying to send data from server to client in Python sockets

I am trying to use "vanilla" Python sockets to transmit data from a server to a client, without using any asynchronous programming. My use case is the following: I would like a local Raspberry Pi to connect to my internet exposed server, and the server to send data through the created socket when a given event occurs.
I followed several tutorials on simple socket programming in Python to build the following code:
server.py
import socket
import time
def server():
PORT = 65432
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('0.0.0.0', PORT))
s.listen(1)
conn,address=s.accept() # accept an incoming connection using accept() method which will block until a new client connects
print("address: ", address[0])
time.sleep(5)
s.send("hey".encode())
conn.close()
return
server()
client.py
import socket
import time
HOST = "my.remote.domain"
PORT = 65432
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
while True :
print(s.recv(1024))
time.sleep(1)
When launching the server and the client on their respective machine, I can see that the connexion is correctly made, since the IP address of the client is printed in the logs of the server. However, after few seconds and before sending any data, I get the following error on the server side:
address: client_ip_address_appears_here
Traceback (most recent call last):
File "main.py", line 32, in <module>
receiver()
File "main.py", line 18, in receiver
s.send("heeey".encode())
BrokenPipeError: [Errno 32] Broken pipe
Meanwhile on the client side, no data is received:
b''
b''
b''
b''
b''
b''
b''
b''
b''
Is there a conceptual problem in the way I try to handle the socket ?
After trying out the code, I think the biggest problem you have is that the server is trying to send on the wrong socket. i.e. this line:
s.send("hey".encode())
should be rewritten like this:
conn.send("hey".encode())
As it is, you are trying to send() on the TCP accepting-socket rather than on the TCP connection to the client, which doesn't make sense. On my (MacOS/X) system, the server process prints this error output:
Jeremys-Mac-mini-2:~ jaf$ python server.py
('address: ', '127.0.0.1')
Traceback (most recent call last):
File "server.py", line 18, in <module>
server()
File "server.py", line 14, in server
s.send("hey".encode())
socket.error: [Errno 57] Socket is not connected

How to read /dev/log?

I would like to directly access to syslog messages from Python by reading /dev/log.
My (very limited) understanding is that the correct way is to read from there is to bind a datagram socket.
import socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
sock.bind('/dev/log')
sock.listen(1)
while True:
data, addr = sock.recvfrom(1024)
print(data)
Apparently /dev/log is in use:
Traceback (most recent call last):
File "readlog.py", line 4, in <module>
sock.bind('/dev/log')
OSError: [Errno 98] Address already in use
How should I read /dev/log from Python?
EDIT: per #Barmar's comment - only one process can access /dev/log so that part is clear, the device must be clean before reading from it. sudo lsof /dev/log does not show anything.
A answer in a Java thread around this subject mentioned that syslog should be shut down before. I also tried that, lsof | grep "/dev/log" was empty but I got the error nevertheless.
Isn't it possible to have several processes reading from /dev/log?
There is a socket flag to set, in order to prevent this:
socket.SO_REUSEADDR
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
This flag tells the kernel to reuse a local socket in TIME_WAIT state, without waiting for its natural timeout to expire.
Ref: https://docs.python.org/3/library/socket.html

Getting started with network programming in Python

I am quite new to Python, and even newer to network programming.
I'm starting with this example from docs.python.org:
Server:
# Echo server program
import socket
HOST = '' # Symbolic name meaning all available interfaces
PORT = 50007 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
data = conn.recv(1024)
if not data: break
conn.sendall(data)
conn.close()
Client:
# Echo client program
import socket
HOST = 'localhost' # The remote host
PORT = 50007 # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall('Hello, world')
data = s.recv(1024)
s.close()
print 'Received', repr(data)
The original code listed some other address as host, I've changed it to
localhost. The first time I ran the programs they were stopped by the firewall,
but I let it make an exception, and that has not been a problem since.
However, neither of the programs work. The server program gets this error:
Traceback (most recent call last):
File "C:\Users\Python\echoclient.py", line 7, in <module>
s.connect((HOST, PORT))
File "C:\Python27\lib\socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
error: [Errno 10061] Det gick inte att göra en anslutning eftersom måldatorn aktivt nekade det
("A connection could not be made because the target computer actively denied it")
The client program gets this error:
Traceback (most recent call last
File "C:\Users\Python\echoclient.py", line 9, in <module> data = s.recv(1024)
error: [Errno 10054] En befintlig anslutning tvingades att stänga av fjärrvärddatorn
("Existing connection was forced to close by remote host")
I am using Python 2.7.6. How do I make this work?
Question already asked here : Errno 10061 in python, I don't know what do to
When you have a problem with a network connection on windows, check the Errno number to understand.
In your case, since you are running the app on localhost, maybe you have a firewall rule blocking the server script to bind with port on machine.
To check if app is listening:
On windows, open a cmd prompt (run as Administrator):
netstat -ban | findstr "50007"
On Linux :
netstat -ltnp | grep 50007
=> If you don't see anything returned, it means nothing is listening on this port.
=> If you see something, check it is your app.
If so, check your firewall rules, antivirus ( best is to disable all sec if you are troubleshooting and it is a test machine)
On windows, go to firewall settings
On Linux, iptables -L -n as root ( or sudo)

getting a socket.gaierror Error 2 when using an actual hostname defined in /etc/hosts, but do not get error with localhost

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.

Categories