I am experimenting with import sockets in python and I have a client.py and a server.py and when server.py receives a message from client.py I get this error
Traceback (most recent call last):
File "C:/Users/Owner/PycharmProjects/pythonProject/echo_server.py", line 13, in <module>
data = conn.recv(1024)
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
My full code is:
import socket
host = ''
port = 12345
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
print(host , port)
s.listen(1)
conn, addr = s.accept()
print('Connected by', addr)
while True:
data = conn.recv(1024)
data = str(data)
if not data: break
print("Client Says: "+data)
conn.sendall(b"Server Says:Message Received")
input(">")
conn.close()
Can someone tell me what this error is and what I can do to fix it?
The if statement if not data is equivalent to writing if data != "", while the empty string your server receives is b''. You have several options to fix it.
data = conn.recv(1024).decode() is the proper way to allocate the data sent by the client. You can now print(data) or compare data to an empty string.
If you still don't want to decode() your message you could change your if statement to if data != b'' or if data is not None.
Update
If it wasn't clear, your str(data) conversion causes the if statement to work unproperly, which is set to False without allowing you to break when a client disconnects.
Related
I am trying to simply send a list from one computer to another.
I have my server set up on one computer, where the IP address is 192.168.0.101
The code for the server:
import socket
import pickle
import time
import errno
HEADERSIZE = 20
HOST = socket.gethostbyname(socket.gethostname())
PORT = 65432
print(HOST)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(10)
while True:
conn, adrs = s.accept()
print(f"Connection with {adrs} has been established")
conn.setblocking(1)
try:
data = conn.recv(HEADERSIZE)
if not data:
print("connection closed")
conn.close()
break
else:
print("Received %d bytes: '%s'" % (len(data), pickle.loads(data)))
except socket.error as e:
if e.args[0] == errno.EWOULDBLOCK:
print('EWOULDBLOCK')
time.sleep(1) # short delay, no tight loops
else:
print(e)
break
The client is on another computer. The code:
import socket
import pickle
HOST = '192.168.0.101'
PORT = 65432
def send_data(list):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(10)
print(".")
print(s.connect_ex((HOST, PORT)))
print(".")
data = pickle.dumps(list)
print(len(data))
s.send(data)
s.close()
send_data([1,1,1])
The outputted error number of connect_ex is 10035. I read a lot about the error, but all I found was about the server side. To me, it looks like the problem is with the client and that it is unable to make a connection to 192.168.0.101. But then, I don't understand why the error I get is about non-blocking.
What is it that I am doing wrong that I am unable to send data?
First of all, how user207421 suggested, change the timeout to a longer duration.
Also, as stated here Socket Programming in Python raising error socket.error:< [Errno 10060] A connection attempt failed I was trying to run my server and connect to a private IP address.
The fix is: on the server side, in the s.bind, to leave the host part empty
HOST = ''
PORT = 65432
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
And on the client side, use the public IP of the PC where the server is running (I got it from ip4.me)
HOST = 'THE PUBLIC IP' #not going to write it
PORT = 65432
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, PORT))
I'm doing an assignment regarding socket programming in python using a client and server. I'm currently on windows 10. Before getting into the little details of the assignment, I've been trying to simply connect the server and client.
Every time I try to run the client file, I would get this error
File "tcpclient.py", line 9, in <module>
s.connect((host, port))
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
I have opened the firewall ports and still nothing. I've tried replacing host with '', 0.0.0.0, socket.gethostname() in both the client and server file but the error still persists. I've even tried different port numbers but it made no difference. I've tried running this code on Ubuntu and Max and I get the same error - connection refused. I've been researching for many solutions but I still have yet to find one that works. Any help would be greatly appreciated!
Note: this code was taken online but it's essentially the basis of what I need to accomplish.
tcpclient.py
import socket
host = '127.0.0.1'
port = 80
buffer_size = 1024
text = "Hello, World!"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.send(text)
data = s.recv(buffer_size)
s.close()
print("received data:", data)
tcpserver.py
import socket
host = '127.0.0.1'
port = 80
buffer_size = 20
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(1)
conn, addr = s.accept()
print 'Connection address:', addr
while 1:
data = conn.recv(buffer_size)
if not data: break
print("received data:", data)
conn.send(data) # echo
conn.close()
Just use a different port. Both the client and server should have the same port and host if not it won't work. Make sure to run the server before the client script.
For client.py
import socket
host = '127.0.0.1'
port = 9879
buffer_size = 1024
text = "Hello, World!"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
text = text.encode('utf-8')
s.send(text)
data = s.recv(buffer_size)
s.close()
print("received data:", data)
For server.py
import socket
mysocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
buffer_size = 1024
text = "Hello, World!"
mysocket.bind(('127.0.0.1', 9879))
mysocket.listen(5)
(client, (ip,port)) = mysocket.accept()
print(client, port)
client.send(b"knock knock knock, I'm the server")
data = client.recv(buffer_size)
print(data.decode())
mysocket.close()
Just change the port number and it will work and if you are in python3 then you will have to encode and decode as socket recieves and sends only binary strings.
I have succeed in my server!
My server python script is below:
import socket
host='0.0.0.0'
port=2345
s=socket.socket()
s.bind((host,port))
s.listen(2)
while True:
conn,addr=s.accept()
print("Connected by",addr)
data=conn.recv(1024)
print("received data:",data)
conn.send(data)
conn.close()
My Client python script is below:
import socket
s=socket.socket()
host="xx.xx.xx.xx" #This is your Server IP!
port=2345
s.connect((host,port))
s.send(b"hello")
rece=s.recv(1024)
print("Received",rece)
s.close()
There is two points needed to be careful in the script:
1.The host of the Server must is
'0.0.0.0'
So that the python script could user all interfaces in the server
2.I have find the question's error through the prompt:
TypeError: a bytes-like object is required, not 'str'
It means every string message in the 'send' method need to convert to 'bytes-like object',So the correct is
s.send(b"hello")
It is important that this is b'hello' not is 'hello'
I was following a tutorial that used threading to start the server. Once I removed the threading then I was able to connect to it.
I have learned the differences between the two infamous errors in tcp:
[Errno 54] Connection reset by peer
[Errno 32] Broken pipe
Both errors are one side of the tcp connection closed for unknown reason, and the other side still communicate with it.
when the other side write something, Broken pipe is thrown
when the other side read something, Connection reset by peer is thrown
I was able to reproduce Broken pipe using Python codes below.
# tcp_server.py
def handler(client_sock, addr):
try:
print('new client from %s:%s' % addr)
finally:
client_sock.close() # close current connection directly
if __name__ == '__main__':
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('', 5500))
sock.listen(5)
while 1:
client_sock, addr = sock.accept()
handler(client_sock, addr)
As for client,
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> sock.connect(('', 5500))
>>> sock.send('a')
1
>>> sock.send('a')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
socket.error: [Errno 32] Broken pipe
When the client first send, a RST packet is sent from server to client, from this moment on, send will always throw Broken pipe.
Everything above is within my understanding. However when client read from server , it always return empty string instead of throw Connection reset by peer
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> sock.connect(('', 5500))
>>> sock.recv(1024)
''
>>> sock.recv(1024)
''
>>> sock.recv(1024)
''
>>> sock.recv(1024)
I am confused at this, or generally how to reproduce the Connection reset by peer ?
You can set the socket "linger" option to 0 and close the socket to send a reset. Updating your server
import socket
import struct
import time
# tcp_server.py
def handler(client_sock, addr):
try:
print('new client from %s:%s' % addr)
time.sleep(1)
finally:
client_sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
struct.pack('ii', 1, 0))
client_sock.close() # close current connection directly
if __name__ == '__main__':
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', 5500))
sock.listen(5)
while 1:
client_sock, addr = sock.accept()
handler(client_sock, addr)
And running this client
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('', 5500))
print(sock.recv(1024))
I got
Traceback (most recent call last):
File "tcpclient.py", line 5, in <module>
print(sock.recv(1024))
ConnectionResetError: [Errno 104] Connection reset by peer
I am playing with socket and tried to create simple chat server with only one client connection. Code and output as follows.
echo_server.py
import socket
host = ''
port = 4538
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
print "Starting Server"
while 1:
client, address = s.accept()
try:
data = client.recv(size)
if data is not None:
if data is 'q':
print "I received request to close the connection"
client.send('q')
continue
print "I got this from client {}".format(data)
client.send(data)
continue
if data == 0:
client.close()
finally:
client.close()
echo_client.py
import socket
host = ''
port = 4538
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
try:
while 1:
message = filename = raw_input('Enter a your message: ')
s.send(message)
data = s.recv(1024)
if data is 'q':
print "You requested to close the connection"
break
print "Received from socket {}".format(data)
finally:
s.close()
Now, I had tried with sendall() too but it doesn't work. Following is the output on both sides
client:
Enter a your message: hello
Received from socket hello
Enter a your message: world
Received from socket
Enter a your message: hi
Traceback (most recent call last):
File "echo_client.py", line 12, in <module>
s.send(message)
socket.error: [Errno 32] Broken pipe
And on server
Starting Server
I got this from client hello
As you can see, the server doesn't get the second message(world). And replies with nothing and when I send third request to server with hi, client terminates with Broken Pipe
How do I go about fixing it?
EDIT 1:
I changed the code now it's following. The s.accept() gets stuck in second request. Following is the code.
echo_server.py
import socket
host = ''
port = 4538
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
print "Starting Server"
try:
while 1:
print "BEFORE REQUEST"
client, address = s.accept()
print "AFTER REQUEST"
data = client.recv(size)
if data:
if data is 'q':
print "I received request to close the connection"
client.send('q')
print "I got this from client {}".format(data)
client.send(data)
else:
print "CLOSING IN ELSE"
client.close()
except:
print "CLOSING IN except"
client.close()
Following is the output.
BEFORE REQUEST
AFTER REQUEST
I got this from client hello
BEFORE REQUEST
As you can see for the second time accept() never returns. How to make it working?
recv returns empty string when the client is closes the connection, not None or 0. Since empty string is a False condition, simply use if data: or if not data:.
And, as #JonClements pointed out, use an except instead of a finally in the server, or put the while inside the try and if not data: break to exit the while and execute the finally.
I am learning socket programming using python. my first assignment is to a write a client.py and a server.py. The client sends a message to server. The server receives the message of 16 bytes each time. After it has received the entire message, it will send the same message back to client.
so it is very simple. The server has backlog of 1. After the server sends the message to client, the connection to client close and the server should be open to receive new connection.
my current code fails in the last step. It is not open to receive new connections. It is throwing error. I even figured out the error. but I do not know how to fix this.
The error comes from server.py because I call for sock.accept() but I have closed the sock.
Let me explain my server.py code: I have two while loops. The outer loop looks for new connection, and the inner loop looks process request from connections i.e it simply receives data, wait till everything is received and send it back to client and finally close the connection.
I am asked not to change the structure of two while loops but just implement them.
Any thoughts or ideas on this:
client.py
import socket
import sys
def client(msg, log_buffer=sys.stderr):
server_address = ('localhost', 10000)
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.IPPROTO_IP)
sock.connect(server_address)
print >>log_buffer, 'connecting to {0} port {1}'.format(*server_address)
try:
print >>log_buffer, 'sending "{0}"'.format(msg)
sock.sendall(msg)
chunk = ''
done=False;
while not done:
chunk+=sock.recv(16)
if chunk==msg:
done=True
print >>log_buffer, 'received "{0}"'.format(chunk)
finally:
print >>log_buffer, 'closing socket'
sock.close()
if __name__ == '__main__':
if len(sys.argv) != 2:
usg = '\nusage: python echo_client.py "this is my message"\n'
print >>sys.stderr, usg
sys.exit(1)
msg = sys.argv[1]
client(msg)
Server.py
import socket
import sys
def server(log_buffer=sys.stderr):
# set an address for our server
address = ('127.0.0.1', 10000)
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.IPPROTO_IP)
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
# log that we are building a server
print >>log_buffer, "making a server on {0}:{1}".format(*address)
sock.bind(address)
sock.listen(1)
try:
# the outer loop controls the creation of new connection sockets. The
# server will handle each incoming connection one at a time.
while True:
print >>log_buffer, 'waiting for a connection'
conn,add=sock.accept()
addr=(conn,add)
try:
print >>log_buffer, 'connection - {0}:{1}'.format(*addr)
# the inner loop will receive messages sent by the client in
# buffers. When a complete message has been received, the
# loop will exit
data = ''
while True:
recvdata=conn.recv(16)
print recvdata
data+=recvdata
print >>log_buffer, 'received "{0}"'.format(data)
print >>log_buffer, "len of received data: {0}".format(len(recvdata))
if len(recvdata)<16:
print >>log_buffer,"sending data"
conn.sendall(data)
break
conn.close()
finally:
sock.close()
except KeyboardInterrupt:
sock.close()
if __name__ == '__main__':
server()
sys.exit(0)
I runpython server.py in one terminal andpython client.py "This is the first message. send me back"` in a different terminal. The client connection is lost normally as expected. But I get the following error at server side (towards the end):
making a server on 127.0.0.1:10000
waiting for a connection
connection - <socket._socketobject object at 0x100849c20>:('127.0.0.1', 50626)
sairam hopefully
received "sairam hopefully"
len of received data: 16
this works lets
received "sairam hopefully this works lets"
len of received data: 16
c
received "sairam hopefully this works lets c"
len of received data: 2
sending data
waiting for a connection
Traceback (most recent call last):
File "echo_server.py", line 89, in <module>
server()
File "echo_server.py", line 39, in server
conn,add=sock.accept()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 202, in accept
sock, addr = self._sock.accept()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 170, in _dummy
raise error(EBADF, 'Bad file descriptor')
socket.error: [Errno 9] Bad file descriptor
You are closing sock inside your while loop. Don't do that. sock is your long-lasting server socket, which needs to remain open to listen for new connections. conn is your ephemeral socket, which needs to remain open only the length of a single connection.
Close conn after each connection, close sock when the server needs to terminate.
More simply, replace these lines:
finally:
sock.close()
with
finally:
conn.close()
What you are trying to do is a simple echo server, which I believe you can implement much more simply.
Server:
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()
Client:
import socket
host = 'localhost'
port = 50000
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
s.send('Hello, world')
data = s.recv(size)
s.close()
print 'Received:', data