Python - Client and server communication - python

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?

Related

Socket WinError 10022 but only as an executable on a Networkdrive

I've got an XML file from which I parse a host adress + port. My script is supposed to establish a connection to every host over the given port (only port 22 ATM) to check the availability of the devices. Every host with which a connection is not possible is to be noted in a List.
file = minidom.parse('Sessions.XML')
sessiondata_all = file.getElementsByTagName('SessionData')
failed_ips = []
def check_port(host, port):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.bind(('', 22))
sock.listen(1)
sock.accept()
if not sock.connect_ex((host, int(port))) == 0:
failed_ips.append(host)
sock.close()
def main():
try:
for sessiondata in sessiondata_all:
host = sessiondata.attributes['Host'].value
port = sessiondata.attributes['Port'].value
print(host + ":" + port)
check_port(host, port)
except Exception as e:
logging.error(traceback.format_exc())
print(failed_ips)
if __name__ == '__main__':
main()
This code is successful if I run it as a .py or .exe (pyinstaller --onefile [Filename.py]) locally. It also works on a networkdrive as a .py but as soon as I try it as an executable I get the following Error:
PS [Directory on the Networkdrive] .\FailedIps.exe
1.1.1.1
ERROR:root:Traceback (most recent call last):
File "FailedIps.py", line 101, in main
File "FailedIps.py", line 68, in check_port
File "socket.py", line 232, in __init__
OSError: [WinError 10022] An invalid argument was supplied
[]
Anybody got an idea what's the matter here? I can't figure it out
Python and Pyinstaller are on current versions
You should swap out
socket.bind(('',22))
to
socket.bind((host,22))

Socket Error: 111 [.connect((host, port))]

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

Creating non-blocking socket in python

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.

Python server chat issue when run

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()

socket server on a thread not releasing the port after the process terminates

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.

Categories

Resources