I am writing a Python client which connects with simple sockets in a server (also written in Python). I want to prevent client termination when the connection in server refused. In other words, I want to make client "search" for the server (if there is no connection) every 30 seconds.
Here is the code I wrote, but when the connection terminates from the server, the client returns an error for connection refused, and terminates itself.
Code:
#!/usr/bin/python
import socket
import time
while True:
sock = socket.socket()
host = socket.gethostname()
port = 4444
conn = sock.connect((host,port))
while(conn != None):
print 'Waiting for the server'
time.sleep(30)
sock = socket.socket()
host = socket.gethostname()
port = 4444
conn = sock.connect((host,port))
while True:
recv_buf = sock.recv(1024)
if (recv_buf == 'exit'):
break
print(recv_buf)
sock.send('hi server')
Error:
Traceback (most recent call last): File "s_client.py", line 12, in
conn = sock.connect((host,port)) File "C:\Program Files\python27\lib\socket.py", line 224, in meth
return getattr(self._sock,name)(*args) socket.error: [Errno 10061] ─ίΊ ▐ΪάΊ ϊΫΊάΪ▐ ύ ϊύΉώΎΫ±ή▀ά ≤²Ίϊί≤ύ≥,
So any idea, that will help not to terminate the client, but to make it continuously look for the server, is welcome.
Use try-except:
conn = None
while(conn == None):
sock = socket.socket()
host = socket.gethostname()
port = 4444
try:
conn = sock.connect((host,port))
except:
print 'Waiting for the server'
time.sleep(30)
It's better to avoid the initial connect call and perform the connect only through the connect in the while loop. I have made a few other changes too, like moving the sleep call to the except part.
Related
I am learning socket programing using Python with simple example. But in local PC client able to connect with server. When I want to test same code in two different computers below is the error.
File "C:\Python27\lib\socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 10060] A connection attempt failed because the connected pa
rty did not properly respond after a period of time, or established connection f
ailed because connected host has failed to respond
Server
import socket
s = socket.socket()
print("after socket creation")
s.bind(("",9999))
hostname = socket.gethostname()
IPAddr = socket.gethostbyname(hostname)
print("IPAddr: "+IPAddr);
print("listening")
s.listen(5)
while True:
clt,adr = s.accept()
print(f"connection to {adr} established")
clt.send(bytes("info from server", "utf-8"))
client
import socket
# host name is output of IPAddr = socket.gethostbyname(hostname) another PC
s = socket.socket()
s.connect((host,9999))
msg = s.recv(100)
print(msg.decode("utf-8"))
Please help me to resolve the issue,Thanks in advance
the code of socket-server and the code of socket-client can run perfectly on my localhost, but when I run the code of socket-server on Ubuntu server, the code of socket-client on my localhost can't connect to Ubuntu server.And the code of socket-client on Ubuntu Server can't connect to my localhost Server.
socket-server.py
import socket
import threading
def bbs(conn):
user_list.append(conn)
try:
while 1:
msg = conn.recv(1024)
if msg:
for user in user_list:
user.send(msg)
except ConnectionResetError:
user_list.remove(conn)
conn.close()
user_list = []
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('0.0.0.0', 18000))
server.listen()
while 1:
conn, addr = server.accept()
t = threading.Thread(target=bbs, args=(conn,))
t.start()
socket-client.py
import socket
import threading
import time
def send_msg():
while 1:
msg = input()
client.send((name + ':' + msg).encode('utf-8'))
def recv_msg():
while 1:
msg = client.recv(1024)
if msg:
try:
print(msg.decode('utf-8'))
time.sleep(1)
except UnicodeDecodeError:
pass
name = input('请输入你的昵称:')
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('10.26.8.132', 18000))
sendmsg_thread = threading.Thread(target=send_msg)
recvmsg_thread = threading.Thread(target=recv_msg)
sendmsg_thread.start()
recvmsg_thread.start()
Server is always wait for connection, Client report an error:
TimeoutError: [WinError 10060] The connection attempt failed because the connecting party did not respond correctly after a period of time or because the connecting host did not respond.
Wang if this works without issue on your localhost, but not over a network connection, it might be a firewall issue on both client & server. You can use 'nc' (netcat) for testing the connection from client to the server.
Simple client - server app.
#Server use decode
import socket
s = socket.socket()
host = socket.gethostname()
port = 12345
s.bind((host,port))
s.listen(5)
while True:
c,addr = s.accept()
print("Got connection from " + str(addr))
ret_val = s.send("Thank you".encode('utf-8'))
print ("ret_val={}".format(ret_val))
c.close()
Client:
#client use decode
from socket import gethostname, socket
serSocket = socket()
server = gethostname()
port = 12345
serSocket.connect((server, port))
data = serSocket.recv(1024)
msg = data.decode('utf-8')
print("Returned Msg from server: <{}>".format(msg))
serSocket.close()
when the server tries to send the following exception occurred
Traceback (most recent call last):
Got connection from ('192.168.177.1', 49755)
File "C:/Users/Oren/PycharmProjects/CientServer/ServerSide/Server2.py", line 16, in <module>
ret_val = s.send("Thank you".encode('utf-8'))
OSError: [WinError 10057] A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied
Process finished with exit code 1
As can be seen the client connects the server successfully.
But send fails.
What is the problem?
The problem is that you are sending on the listening socket, not on the connected socket. connect returns a new socket which is the one you must use for data transfer. The listening socket can never be used for sending or receiving data.
Change the send to this and your program will work fine:
ret_val = c.send("Thank you".encode('utf-8'))
(Note c.send, not s.send)
It's my client:
#CLIENT
import socket
conne = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conne.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
i=0
while True:
conne.connect ( ('127.0.0.1', 3001) )
if i==0:
conne.send(b"test")
i+=1
data = conne.recv(1024)
#print(data)
if data.decode("utf-8")=="0":
name = input("Write your name:\n")
conne.send(bytes(name, "utf-8"))
else:
text = input("Write text:\n")
conne.send(bytes(text, "utf-8"))
conne.close()
It's my server:
#SERVER
import socket
counter=0
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('', 3001))
sock.listen(10)
while True:
conn, addr = sock.accept()
data = conn.recv(1024)
if len(data.decode("utf-8"))>0:
if counter==0:
conn.send(b"0")
counter+=1
else:
conn.send(b"1")
counter+=1
else:
break
print("Zero")
conn.send("Slava")
conn.close()
))
After starting Client.py i get this error:
Traceback (most recent call last): File "client.py", line 10, in
conne.connect ( ('127.0.0.1', 3001) ) OSError: [Errno 9] Bad file descriptor
Problem will be created just after first input.
This program - chat. Server is waiting for messages. Client is sending.
There are a number of problems with the code, however, to address the one related to the traceback, a socket can not be reused once the connection is closed, i.e. you can not call socket.connect() on a closed socket. Instead you need to create a new socket each time, so move the socket creation code into the loop:
import socket
i=0
while True:
conne = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conne.connect(('127.0.0.1', 3001))
...
Setting socket option SO_BROADCAST on a stream socket has no affect so, unless you actually intended to use datagrams (UDP connection), you should remove the call to setsockopt().
At least one other problem is that the server closes the connection before the client sends the user's name to it. Probably there are other problems that you will find while debugging your code.
Check if 3001 port is still open.
You have given 'while True:' in the client script. Are you trying to connect to the server many times in an infinite loop?
I'm working on a bit of a project in python. I have a client and a server. The server listens for connections and once a connection is received it waits for input from the client. The idea is that the client can connect to the server and execute system commands such as ls and cat. This is my server code:
import sys, os, socket
host = ''
port = 50105
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
print("Server started on port: ", port)
s.listen(5)
print("Server listening\n")
conn, addr = s.accept()
print 'New connection from ', addr
while (1):
rc = conn.recv(5)
pipe = os.popen(rc)
rl = pipe.readlines()
file = conn.makefile('w', 0)
file.writelines(rl[:-1])
file.close()
conn.close()
And this is my client code:
import sys, socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = 'localhost'
port = input('Port: ')
s.connect((host, port))
cmd = raw_input('$ ')
s.send(cmd)
file = s.makefile('r', 0)
sys.stdout.writelines(file.readlines())
When I start the server I get the right output, saying the server is listening. But when I connect with my client and type a command the server exits with this error:
Traceback (most recent call last):
File "server.py", line 21, in <module>
rc = conn.recv(2)
File "/usr/lib/python2.6/socket.py", line 165, in _dummy
raise error(EBADF, 'Bad file descriptor')
socket.error: [Errno 9] Bad file descriptor
On the client side, I get the output of ls but the server gets screwed up.
Your code calls conn.close() and then loops back around to conn.recv(), but conn is already closed.
If you want your client to repeat what it's doing, just add a loop in there ;)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = 'localhost'
port = input('Port: ')
s.connect((host, port))
while True:
cmd = raw_input('$ ')
s.send(cmd)
file = s.makefile('r', 0)
sys.stdout.writelines(file.readlines())
Should probably be closer to what you want.
Other comments:
s.listen(1)
This statement should probably be moved outside of the while loop. You only need to call listen once.
pipe = os.popen(rc)
os.popen has been deprecated, use the subprocess module instead.
file = s.makefile('r', 0)
You're opening a file, yet you never close the file. You should probably add a file.close() after your sys.stdout.writelines() call.
EDIT: to answer below comment; done here due to length and formatting
As it stands, you read from the socket once, and then immediately close it. Thus, when the client goes to send the next command, it sees that the server closed the socket and indicates an error.
The solution is to change your server code so that it can handle receiving multiple commands. Note that this is solved by introducing another loop.
You need to wrap
rc = conn.recv(2)
pipe = os.popen(rc)
rl = pipe.readlines()
fl = conn.makefile('w', 0)
fl.writelines(rl[:-1])
in another while True: loop so that it repeats until the client disconnects, and then wrap that in a try-except block that catches the IOError that is thrown by conn.recv() when the client disconnects.
the try-except block should look like
try:
# the described above loop goes here
except IOError:
conn.close()
# execution continues on...