I have a code where there are 13 clients that have to connect to the server. Then the server does some counting on the data given by the client. After that the roles turns around - the server becomes a client and clients become servers to receive the data.
The thing is that when trying to do the first connection, that is when the 13 clients try to connect to the server I keep getting this error: [Errno 104] Connection reset by peer. I tried some workarounds for example trying to connect 5 times in a second interval but nothing works.
Here my code:
server.py
import socket, pickle, numpy as np
import struct
import math
while 1:
HOST = ''
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(13)
adresses = []
ports = []
i = 0
print("receiving...")
while i < 13:
i += 1
#wait to accept a connection - blocking call
conn, addr = s.accept()
print ('Connected with ', addr)
adresses.append(addr[0])
buf = b''
while len(buf) < 4:
buf += conn.recv(4 - len(buf))
length = struct.unpack('>I', buf)[0]
data = b''
l = length
while l > 0:
d = conn.recv(l)
l -= len(d)
data += d
if not data: break
M = np.loads(data)
if i == 1:
L = M[0]
else:
L += M[0]
ports.append(M[1])
conn.close()
s.close()
L /= 993040
packet = pickle.dumps(L)
length = struct.pack('>I', len(packet))
packet = length + packet
print("sending...")
for kl, addr in enumerate(adresses):
HOST = addr
PORT = 50007 + ports[kl]
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(packet)
s.close()
client.py
def connection(centers, kl):
HOST = "192.168.143.XX"
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(3600)
try:
s.connect((HOST, PORT)) # HERE IS AN ERROR
s.settimeout(None)
packet = pickle.dumps([centers, kl]) ## ???
length = struct.pack('>I', len(packet))
packet = length + packet
s.sendall(packet) # OR HERE IS AN ERROR
s.close()
except Exception as e:
print(e)
print('error ', kl)
s.close()
return np.zeros(centers.shape)
HOST = ''
PORT = 50007 + kl
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(2)
i = 0
while i < 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
i += 1
print ('Connected with ', addr)
buf = b''
while len(buf) < 4:
buf += conn.recv(4 - len(buf))
length = struct.unpack('>I', buf)[0]
data = b''
l = length
while l > 0:
d = conn.recv(l)
l -= len(d)
data += d
if not data: break
new_centers = np.loads(data)
conn.close()
s.close()
return new_centers
aa = 0
for k in range(99):
print(k)
centers = some_function(centers)
time.sleep(60)
centers1 = connection(centers, i)
aa = 0
while not (centers1.any()) and aa < 5:
time.sleep(1)
centers1 = connection(centers, i)
aa += 1
centers = centers1
The thing is all of the 13 clients HAVE TO connect to the server or it won't proceed to the next iteration.
I'm using Python 3.4.
Please help.
Update:
I have added threads but the error remains:
[Errno 104] Connection reset by peer
server.py
import socket, pickle, numpy as np
import struct
import math
from multiprocessing.pool import ThreadPool
def clientthread(conn, L):
buf = b''
while len(buf) < 4:
buf += conn.recv(4 - len(buf))
length = struct.unpack('>I', buf)[0]
data = b''
l = length
while l > 0:
d = conn.recv(l)
l -= len(d)
data += d
M = np.loads(data)
return(M)
j = 0
while 1:
HOST = ''
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(2)
#print('0')
adresses = []
ports = []
i = 0
print("receiving...")
while i < 13:
i += 1
#wait to accept a connection - blocking call
conn, addr = s.accept()
print ('Connected with ', addr)
adresses.append(addr[0])
pool = ThreadPool(processes=13)
async_result = pool.apply_async(clientthread, (conn, i,))
M = async_result.get()
conn.close()
if i == 1:
L = M[0]
else:
L += M[0]
ports.append(M[1])
s.close()
L /= 993040
packet = pickle.dumps(L)
length = struct.pack('>I', len(packet))
packet = length + packet
for kl, addr in enumerate(adresses):
HOST = addr
PORT = 50007 + ports[kl]
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(packet)
s.close()
It seems that the clients were connected to the server but they encountered with " [Errno 104] Connection reset by peer" exception when they tried to send data. For the first time, Python raises "[Errno 104] Connection reset by peer" exception, then for the second time and more you would get "[Errno 32] Broken pipe" exception on the client side.
This can mean that the server is up and listening on the port (otherwise, you would get "[Errno 111] Connection refused" exception on the client side". This also means that the server is crashed before closing the connection since if the connection was closed on the server side before sending data on the client side, the client would encounter with "[Errno 32] Broken pipe" exception.
"Connection reset by peer" is the TCP/IP equivalent of slamming the phone back on the hook. It's more polite than merely not replying, leaving one hanging. But it's not the FIN-ACK expected of the truly polite TCP/IP converseur. (From another stackoverflow answer)
You are going to have to use threading on the server.
For a simple explanation see: http://www.binarytides.com/python-socket-server-code-example/
The guts of the simple example given there is:
import socket
import sys
from thread import *
HOST = '' # Symbolic name meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
#Bind socket to local host and port
try:
s.bind((HOST, PORT))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
#Start listening on socket
s.listen(10)
print 'Socket now listening'
#Function for handling connections. This will be used to create threads
def clientthread(conn):
#Sending message to connected client
conn.send('Welcome to the server. Type something and hit enter\n') #send only takes string
#infinite loop so that function do not terminate and thread do not end.
while True:
#Receiving from client
data = conn.recv(1024)
reply = 'OK...' + data
if not data:
break
conn.sendall(reply)
#came out of loop
conn.close()
#now keep talking with the client
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
#start new thread takes 1st argument as a function name to be run, second is the tuple of arguments to the function.
start_new_thread(clientthread ,(conn,))
s.close()
I had this exact error when trying to connect to a remote redis instance from python, because I had mistakenly left Fiddler running and it was interfering with the requests.
Related
I've made a code which is able to receive data from the port over TCP protocol. I receive data from ESP8266 every 15 minutes, and then ESP goes to a deepSleep mode. How to change it to make it work continuosly? I wanted to create a new connection in while loop, but it doesn't work.
My code
import sys
import socket
TCP_IP = '192.168.42.1'
TCP_PORT = 8888
BUFFER_SIZE = 1024
param = []
i=0
#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#s.bind((TCP_IP,TCP_PORT))
#s.listen(1)
#print 'Listening for client...'
#conn, addr = s.accept()
#print 'Connection address:', addr
while 1:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP,TCP_PORT))
s.listen(1)
print 'Listening for client...'
conn, addr = s.accept()
print 'Connection address:', addr
data = conn.recv(BUFFER_SIZE)
if data == ";" :
conn.close()
print "Received all the data"
i=0
for x in param:
print x
#break
elif data:
print "received data: ", data
param.insert(i,data)
i+=1
#print "End of transmission"
EDIT:
My code after modification.
import sys
import socket
TCP_IP = '192.168.42.1'
TCP_PORT = 8888
BUFFER_SIZE = 1024
param = []
i=0
#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#s.bind((TCP_IP,TCP_PORT))
#s.listen(1)
#print 'Listening for client...'
#conn, addr = s.accept()
#print 'Connection address:', addr
while 1:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP,TCP_PORT))
s.listen(1)
while 1:
print 'Listening for client...'
conn, addr = s.accept()
print 'Connection address:', addr
data = conn.recv(BUFFER_SIZE)
if data == ";" :
conn.close()
print "Received all the data"
i=0
for x in param:
print x
#break
elif data:
print "received data: ", data
param.insert(i,data)
i+=1
#print "End of transmission"
s.close()
I created second while loop. I can listen continuously now, but I receive only one packet from the ESP (ESP send 9 packets). How to solve that issue?
If you want to continuously listen for connections and data from your remote end, you can achieve this using select()
A modified version of your code that uses select() is shown below. This will also handle the remote end closing the connection:
import sys
import socket
import select
TCP_IP = '127.0.0.1'
TCP_PORT = 8888
BUFFER_SIZE = 1024
param = []
print 'Listening for client...'
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((TCP_IP,TCP_PORT))
server.listen(1)
rxset = [server]
txset = []
while 1:
rxfds, txfds, exfds = select.select(rxset, txset, rxset)
for sock in rxfds:
if sock is server:
conn, addr = server.accept()
conn.setblocking(0)
rxset.append(conn)
print 'Connection from address:', addr
else:
try:
data = sock.recv(BUFFER_SIZE)
if data == ";" :
print "Received all the data"
for x in param:
print x
param = []
rxset.remove(sock)
sock.close()
else:
print "received data: ", data
param.append(data)
except:
print "Connection closed by remote end"
param = []
rxset.remove(sock)
sock.close()
NB I've replaced your IP address with the loopback but you get the idea.
Hope this may be helpful.
I'm building a tcp/ip server in python that works with clients.
Each client gets its own thread and its socket is added to a list called client_list.
there also is a variable "clients_connected" which stores the amount of connected clients.
for some reason it just works with one client at the moment.
Also when a client disconnects, it should be removed from client_list but I'm not sure how to do that.
Could you take a look at the code please? thanks a lot!
this thread is looking for incoming connections:
def addclientsthread(sock):
global client_list
conn, addr = sock.accept()
client_list += [conn]
print_line('Client connected on ' + addr[0] + "\n")
start_new_thread(clientthread, (conn,))
So when a client connects it gets its own "clientthread"
def clientthread(conn):
# handling connections.
global clients_connected
while True:
# Receiving from client
in_data = conn.recv(1024)
data = decrypt(in_data)
if data.lower().find("id=-1") != -1:
clients_connected += 1
print_line("new client ID set to " + str(clients_connected) + "\n")
crypted_msg = encrypt("SID=" + str(clients_connected))
conn.sendall(crypted_msg)
pass
elif data.lower().find("uin") == 0:
uin_id = int(data[4:])
clients_connected -= 1
break
else:
print_line(data)
if not data:
break
# If client disconnects
conn.close()
Oh and please don't hate, I just started coding :)
EDIT: This is the main code (not in a thread)
HOST = ''
PORT = 8820
clients_connected = 0
client_list = []
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Socket created')
# Bind socket to host and port
try:
s.bind((HOST, PORT))
except socket.error, msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket successfully binded'
# Start listening on socket
s.listen(100000)
print 'Socket is listening'
start_new_thread(addclientsthread, (s,))
I have a Moxa device that create Tcp-ip message from serial data and send them to me by LAN.
i need to listen to hes specific external-ip(172.16.0.77) with python server.
ill try to do this:
BUFFER_SIZE = 10000 # Normally 1024, but we want fast response
HOST = self.TCP_IP #(172.16.0.77)
PORT = self.TCP_PORT # Arbitrary non-privileged port
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,
socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
af, socktype, proto, canonname, sa = res
try:
s = socket.socket(af, socktype, proto)
except socket.error as msg:
print msg
s = None
continue
try:
s.bind(sa)
s.listen(1)
except socket.error as msg:
print msg
s.close()
s = None
continue
break
if s is None:
print 'could not open socket'
while s:
print s.getsockname()
conn, addr = s.accept()
print 'Connection address:', addr
data = conn.recv(BUFFER_SIZE)
if data:
self.emit(QtCore.SIGNAL("SamplesRecive"),data)
conn.close()
and i get : [Errno 10049] The requested address is not valid in its context could not open socket
I need to divide the serves to many Moxa devices so i cant use socket.INADDR_ANY
Any ideas?
socket.INADDR_ANY equal to socket.bind('0.0.0.0')
if bind to "0.0.0.0" can listen all interfaces(which avaible)
Example of Moxa TCP :
import socket,time
import thread
#Example client
class _client :
def __init__(self):
self.status = False
def run(self,clientsock,addr):
while 1 :
try:
data = clientsock.recv(BUFF)
if data :
#do something with data
time.sleep(.1)
if self.status == False:
clientsock.close()
break
clientsock.send(next_query)
except Exception,e :
print e
break
client = _client()
ADDR = ("0.0.0.0", 45500) #so you need port how to decode raw socket data ?
serversock = socket(AF_INET, SOCK_STREAM)
serversock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
serversock.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)#gain 50ms tcp delay
serversock.bind(ADDR)
serversock.listen(10)
While True :
clientsock, addr = serversock.accept()
if addr[0] == device_1_IP:
client.status = True
#start device1 thread(moxa is TCP client mode)
thread.start_new_thread(client.run, (clientsock, addr))
#if client.status = False you will be close connection.
But my offer is "use moxa with TCP server mode"
i am used 4x5450i 3x5250 over 120 device without any error.
I am writing a simple TCP server in python, and am trying to input a timeout. My current code:
import socket
def connect():
HOST = '' # Symbolic name meaning the local host
PORT = 5007 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
s.settimeout(5)
conn, addr = s.accept()
print 'Connected by', addr
return conn
conn = connect()
while 1:
data = conn.recv(1024)
if not data: break
print data
conn.close()
Issue is when I try to connect I get an error at data = conn.recv(1024)
error: [Errno 10035] A non-blocking socket operation could not be completed immediately
Code works without the timeout.
You can turn on blocking:
# ...
conn.setblocking(1)
return conn
# ...
Try to set the timeout on the socket and the blocking on the connection. Like this:
import socket
def connect():
HOST = '' # Symbolic name meaning the local host
PORT = 5007 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)
s.bind((HOST, PORT))
s.listen(1)
return s
s = connect()
while 1:
conn, addr = s.accept()
print 'Connected by', addr
conn.setblocking(1)
data = conn.recv(1024)
conn.close()
if not data: break
print data
s.close()
Ran into the same problem 30 minutes ago. Found a simple non-elegant work around...if you give the socket time to breathe by doing time.sleep(1), catching the 10035 error and doing a retry it works. I'm using 2.7.5...maybe this is a bug that got fixed. Not real sure.
Code sample...please understand this is very simplistic test code I use (only recv 1 byte at a time).So where 's' is the socket with a 10s timeout and 'numbytes' is number of bytes I need...
def getbytes(s,numbytes):
din = ''
socketerror10035count = 0
while True:
try:
r = s.recv(1).encode('hex')
din += r
if len(din)/2 == numbytes:
print 'returning',len(din)/2, 'bytes'
break
except socket.timeout as e:
din = 'socket timeout'
break
except socket.error as e:
if e[0] == 10035 and socketerror10035count < 5:
socketerror10035count = socketerror10035count +1
time.sleep(1)
else:
din = 'socket error'
break
except:
din = 'deaddead'
break
return din
For Python 3 and above, the above code which references e as a scriptable object will need to be changed to "e.errno". And, of course the print statements require parenthesis around the arguments.
Additionally, you may want to change the "except socket.error as e:" line to "except BlockingIOError as e:". However, the code works as is under Python 3.8.5 on Windows.
Server
import socket
import sys
HOST = ''
PORT = 9000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
try:
s.bind((HOST, PORT))
except socket.error , msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
s.listen(10)
print 'Socket now listening'
conn, addr = s.accept()
print 'Connecting from: ' + addr[0] + ':' + str(addr[1])
while 1:
message=raw_input(">")
s.sendto(message, (addr[0], addr[1]))
print(s.recv(1024))
How do I make this send a message to the client?
I can make it reply to a string the client sends to the server, but in this case I want the server to send the first message...
Can anyone help me, The solutions on google don't seem to work properly and I'm not sure what I'm doing wrong.
Since this is the 1st Google Stack Overflow result for this, I'll post a complete, working example for both a client and a server. You can start either 1st. Verified working on Ubuntu 18.04 w/ Python 3.6.9
text_send_server.py:
# text_send_server.py
import socket
import select
import time
HOST = 'localhost'
PORT = 65439
ACK_TEXT = 'text_received'
def main():
# instantiate a socket object
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('socket instantiated')
# bind the socket
sock.bind((HOST, PORT))
print('socket binded')
# start the socket listening
sock.listen()
print('socket now listening')
# accept the socket response from the client, and get the connection object
conn, addr = sock.accept() # Note: execution waits here until the client calls sock.connect()
print('socket accepted, got connection object')
myCounter = 0
while True:
message = 'message ' + str(myCounter)
print('sending: ' + message)
sendTextViaSocket(message, conn)
myCounter += 1
time.sleep(1)
# end while
# end function
def sendTextViaSocket(message, sock):
# encode the text message
encodedMessage = bytes(message, 'utf-8')
# send the data via the socket to the server
sock.sendall(encodedMessage)
# receive acknowledgment from the server
encodedAckText = sock.recv(1024)
ackText = encodedAckText.decode('utf-8')
# log if acknowledgment was successful
if ackText == ACK_TEXT:
print('server acknowledged reception of text')
else:
print('error: server has sent back ' + ackText)
# end if
# end function
if __name__ == '__main__':
main()
text_receive_client.py
# text_receive_client.py
import socket
import select
import time
HOST = 'localhost'
PORT = 65439
ACK_TEXT = 'text_received'
def main():
# instantiate a socket object
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('socket instantiated')
# connect the socket
connectionSuccessful = False
while not connectionSuccessful:
try:
sock.connect((HOST, PORT)) # Note: if execution gets here before the server starts up, this line will cause an error, hence the try-except
print('socket connected')
connectionSuccessful = True
except:
pass
# end try
# end while
socks = [sock]
while True:
readySocks, _, _ = select.select(socks, [], [], 5)
for sock in readySocks:
message = receiveTextViaSocket(sock)
print('received: ' + str(message))
# end for
# end while
# end function
def receiveTextViaSocket(sock):
# get the text via the scoket
encodedMessage = sock.recv(1024)
# if we didn't get anything, log an error and bail
if not encodedMessage:
print('error: encodedMessage was received as None')
return None
# end if
# decode the received text message
message = encodedMessage.decode('utf-8')
# now time to send the acknowledgement
# encode the acknowledgement text
encodedAckText = bytes(ACK_TEXT, 'utf-8')
# send the encoded acknowledgement text
sock.sendall(encodedAckText)
return message
# end function
if __name__ == '__main__':
main()
Use the returned socket object from 'accept' for sending and receiving data from a connected client:
while 1:
message=raw_input(">")
conn.send(message)
print conn.recv(1024)
You just have to use send
Server.py
import socket
s = socket.socket()
port = 65432
s.bind(('0.0.0.0', port))
s.listen(5)
while True:
c, addr = s.accept()
msg = b"Hello World!"
c.send(msg)
Client.py
import socket
s = socket.socket()
port = 65432
s.connect(('127.0.0.1', port))