I'm trying to make communication via Internet between client and server, both written in Python. I have the next code for server:
def handle_client(clnt):
while True:
data = clnt.recv(1024)
if data:
print data,
del data
sock = socket.socket()
sock.bind(('0.0.0.0', 12345))
sock.listen(5)
while True:
client,addr = sock.accept()
print "[*] Accepted connection from: %s:%d" % (addr[0],addr[1])
# spin up our client thread to handle incoming data
client_handler = threading.Thread(target=handle_client,args=(client,))
client_handler.start()
client.close()
and for client:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('my public IP-address', 12345))
sock.send('Some plain text')
When working with localhost, it works properly. After i have loaded it to my Ubuntu-14.04 server, which is not in the same local network, client doesn't want to connect. The output is:
socket.error: [Errno 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
I have already created rule for server firewall, run server and client as administrator, disabled client antivirus, checked the Internet connection, pinged each other but it still doesn't seem to work throwing me the same error over and over again (the same error is shown if the server wasn't started).
Any ideas what`s wrong or how to fix this issue?
Related
I have been trying to create a messaging service in python using sockets. I have written the code to host two connections and allow one to send messages to the other using username and host_addr.
But every time I try to connect the second client and send a message from the first getting the following error.
ConnectionResetError: [Errno 54] Connection reset by peer
Server.py
import socket
import _thread as thread
HOST = "127.0.0.1" # Standard loopback interface address (localhost)
PORT = 1237 # Port to listen on (non-privileged ports are > 1023)
user_mapping = {}
def on_new_client(conn, addr):
data = conn.recv(1024)
data = data.decode()
print(data)
print(user_mapping)
if data[:8] == "username":
user_mapping[data[9:]] = (addr, data[9:])
elif data[0] == "#":
for i in user_mapping.values():
if i[0] == addr:
from_user = i[1]
else:
str = "user not found"
conn.sendto(str.encode(), addr)
str = "%s:%s" % (from_user, data[data.find(":") + 1:])
conn.sendto(str.encode(), user_mapping[data[1:data.find(":")](0)])
else:
pass
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(10)
while True:
conn, addr = s.accept()
thread.start_new_thread(on_new_client,(conn,addr))
s.close()
Client.py
import socket
HOST = "127.0.0.1" # The server's hostname or IP address
PORT = 1237 # The port used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
username = input("Enter user name")
str = "username: %s" % username
s.send(str.encode())
while True:
message = input(username+">")
s.send(message.encode())
data = s.recv(1024)
print(data)
Was hoping some would could answer why this is happening and guide me to any good links where there is Information on creating a messaging service in python.
Client is sending 2 messages and then receiving one.
But server just listen once and then send one or two packages.
Chronologically:
Client sends a package, and server reads it.
Then both client and server try to send a package. Both packages that won't meet a listening peer.
Then client try to receive a package, but server won't send (he already sent it before) or it may send but its too late because communication is already broken.
Concepts you may implement always:
If one talk, another one may listen.
If a package is mean to be sent, it shall be sent anyway. Dont let a 'if' statment that send package when at 'else' that does not (or viceversa).
==== EDIT ====
About solution:
You need to work with paralel loops.
Take a look at this code https://www.neuralnine.com/tcp-chat-in-python/
He uses two threads on client, one for keep listening for new server updates (messages for other people) and another one to wait input from user.
I have an Ipad and a raspberry pi. I want to broadcast a simple message from my ipad to my raspberry pi using python's library: "socket". I have a file called server.py in my raspberry pi. I have another file called client.py in my Ipad. server.py should await a connection from the Ipad, and accept it. client.py should send the broadcast message.
server.py
import socket
import threading
bind_ip = '0.0.0.0'
bind_port = 9999
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((bind_ip, bind_port))
server.listen(5)
print("[*] Listening on {}:{}".format(bind_ip, bind_port))
def handle_client(client_socket):
request = client_socket.recv(1024)
print('received: {}'.format(request))
client_socket.send(b'ACK!')
client_socket.close()
while True:
client, addr = server.accept()
print("[*] Accepted connection from: {}:{}".format(addr[0], addr[1]))
client_handler = threading.Thread(target=handle_client, args=(client,))
client_handler.start()
client.py
import socket
HOST = "0.0.0.0"
PORT = 9999
sock = socket.socket()
print("Attempting connection... ")
sock.connect((HOST, PORT))
print("Connected")
I first ran server.py on my raspberry pi, then ran client.py on my Ipad. However, the following error message greeted me when I ran client.py:
[Errno 61] Connection refused
I made sure the server was running properly, and I checked where the client was connecting to. It should have worked.
Please help me.
I would like to point out that there are so many mistakes in that code. I presume that you are totally new with sockets.
(Also try putting 'your-server's-local-ip' in the bind_ip and HOST in server.py and client.py respectively if both of your server and client are connected to the same network)
Even though you connect with the server you'd still get greeted with another errors.
Let me start with server.py:
In server.py you are using handle_client function to recieving a message from the client while at the client end you are not sending anything.
After that you're recieving the message from the client while the client is not sending anything.
There is no broadcast function for sending the message to every connected client
The main issue is that you've not learned the basics of the sockets, my only suggestion to you would be to, start things small and then increase the complexity but here, that case is totally opposite.
You can also refer to this video to learn the basics : https://youtu.be/u4kr7EFxAKk
If i have simple socket program with server and client programs to send a message how do I modify it to make it work for different networks. (say my friend and i want to send hi from our pcs)
The error message is:
TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
#Server
import socket
host = 'local host'
port = 5000
s = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
s.bind(('', port))
s.listen(1)
c, addr = s.accept()
print("CONNECTION FROM:", str(addr))
c.send(b"Hi")
msg = "Bye.............."
c.send(msg.encode())
c.close()
#Client
import socket
host = 'local host'
port = 5000
s = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
s.connect(('127.0.0.1', port))
msg = s.recv(1024)
while msg:
print('Recived:' + msg.decode())
msg = s.recv(1024)
s.close()
Set up port forwarding on your router. Suppose your local system is the server serving on port 5000 and your friend is the client.
Open an Command Prompt on the server and run ipconfig to get your local IP address. It is usually of the form 192.168.x.x but can vary. It should also be available in your router's status page.
On your router, configure port forwarding for internal IP = local IP, interal port = 5000, external port = 5000.
Your router should also have your external Internet address on its status page. You can also just google whatsmyip. Give that IP and the external port number (5000) to your friend. They use that to connect their client to your server.
I'm a beginner in Python. So I wanted to make if a server shuts down, disconnects, the client just keeps connecting until the server is opened again. I get this error:
File "C:\Users\Laurynas\Desktop\project\client.py", line 24, in reconnect server1.connect((HOST, PORT)) OSError: [WinError 10056] A connect request was made on an already connected socket
Current client.py code:
import socket
import time
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = socket.gethostbyname(socket.gethostname())
PORT = 8888
# Check at the first try
def connect():
try:
server.connect((HOST, PORT))
messages()
except ConnectionRefusedError:
print("reconnecting, please wait...")
time.sleep(0.1)
connect()
# Check at the second, third, etc.
def reconnect():
try:
server1.connect((HOST, PORT))
messages()
except ConnectionRefusedError:
print("reconnecting, please wait...")
time.sleep(0.1)
reconnect()
def messages():
while True:
try:
command = server.recv(1024).decode()
print(command)
except:
reconnect()
pass
connect()
With the exception of listening sockets that are used for many accepts, data sockets cannot be reconnected and reused. On the client side a new socket needs to be created for the new connection and on the server side a new accept needs to be made. The old sockets should also be closed to get them out of the kernel.
This poses a difficulty because a server won't automatically know which client is reconnecting and which higher level activity should be restarted. This has to be baked into the protocol you implement on top of the connection. In HTTP for instance, each GET/PUT/POST reidentifies itself so that the web server knows how to do that, perhaps using a cookie based session id.
Bottom line, you can't keep on calling server.connect to start it up again.
When I try to execute Python server socket program and client socket program (both running in same linux machine) in Linux terminal I don't get any error, server accepts connection and sends data to client successfully.
But when I execute the same programs in python IDLE I get "[Errno 111] Connection refused" error.
What is the difference in both execution?
I'm using serversock.bind(('',port#)) in server
and in client i'm using clientsock.connect(('localhost',port#))
Server.py
import socket
serversock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
host = ''
print host
port = 5800
serversock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversock.bind((host,port))
serversock.listen(2)
try:
while True:
csock,addr = serversock.accept()
print 'Recieved address from %s '% str(addr)
csock.send('hello')
csock.close()
except Exception,e:
print e
client.py
import socket
try:
c = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
host = 'localhost'
port = 5800
c.connect((host,port))
data = c.recv(1024)
print data
except Exception,e:
print e
finally:
c.close()
Server side you must use:
serversock.bind(('',port#)) # binds to port
serversock.listen(5) # actually listen to port and allow 5 incoming calls
conv = serversock.accept() # accept first incoming call
The connection will only be accepted after the listen call, before it, you have only bound a socket, but have not declared that you were ready to accept incoming calls, so they are refused.
With added code, another possible error cause is that you close connection (server side) immediately after sending data. That is bad: the close condition can destroy the socket before the data has actually been sent.
You should use a graceful shutdown:
server side:
csock.send('hello')
csock.shutdown(socket.SHUT_WR) # shutdown the socket
csock.read() # wait the close from peer
csock.close()
client side: you can leave the code as is in your use case you do not send anything to server, so when the client has finished reading it can safely close the socket
Anyway you should close serversock when everything is finished
try:
...
except ...:
...
finally:
serversock.close()