I have a p2p simple chat app in python. A server code receives the IP and port of peers and sends each peer address to another:
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('', 44444))
while True:
clients = []
while True:
data, address = sock.recvfrom(128)
clients.append(address)
sock.sendto(b'ready', address)
if len(clients) == 2:
break
c1 = clients.pop()
c2 = clients.pop()
try:
sock.sendto('{} {} {}'.format(c1[0], c1[1], c2[1]).encode(), c2)
sock.sendto('{} {} {}'.format(c2[0], c2[1], c1[1]).encode(), c1)
except Exception as e:
print(str(e))
In my client code, first I start sending client info to the server (This part works properly):
import socket
import threading
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
sock.bind(('', 40270))
sock.sendto(b'0', ('X.X.X.X', 44444))
while True:
data = sock.recv(1024).decode()
if data.strip() == 'ready':
break
ip, myport, dport = sock.recv(1024).decode().split(' ')
myport = int(myport)
dport = int(dport)
print('\n ip: {} , myport: {} , dest: {}'.format(ip, myport, sport))
This part of the code starts listening to the server after sending the current client's info to the server and when the other client gets connected, it receives its IP and port.
After connecting two clients and exchanging their addresses, a p2p connection is established between them.
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
sock.bind(('', myport))
sock.sendto(b'0', (ip, dport))
print('ready to exchange messages\n')
Then, I run a thread to start listening to the other client like this:
def listen():
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', myport))
while True:
data = s.recv(1024)
print('\rpeer: {}\n> '.format(data.decode()), end='')
listener = threading.Thread(target=listen, daemon=True)
listener.start()
Also, another socket is responsible to send messages:
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', myport))
while True:
msg = input('> ')
s.sendto(msg.encode(), (ip, dport))
After all, as I said before, the server exchange the IP and port of clients properly. But messages were not received by another client after sending.
I think the problem is about the wrong port choice while I do the exchange.
Regards.
It is completely functional on Linux. The problem just occurred on a windows machine.
Related
So. There is a server and a client. The client knows the address of the server based on UDP dgram and sends packets to the server. But strange thing. Packets seem to be leaving, but the server does not read them. That is, in the recv block, he does not see messages until a mutual packet is sent back to the client (knowing his address in advance). And only then he starts to see messages from the client. Tell me please, what is the problem? (I don't use broadcastcasts, because both the server and the client are at a distance).
Code example:
import stun
import socket
import threading
source_ip = "0.0.0.0"
source_port = 9992
external_ip = None
external_port = None
sock = None
def GetIP(ip, port):
global external_ip, external_port, sock
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((ip, port))
sock.settimeout(0.1)
nat_type, nat = stun.get_nat_type(sock, ip, port, stun_host='stun.l.google.com', stun_port=19302)
if nat['ExternalIP']:
external_ip = nat['ExternalIP']
external_port = nat['ExternalPort']
print("my addr: %s:%s\n" % (external_ip, external_port))
sock.shutdown(1)
sock.close()
return ip, port
else:
port += 1
return GetIP(ip, port)
source_ip, source_port = GetIP(source_ip, source_port)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((source_ip, source_port))
data = None
remote_ip, remote_port = input(
"input `addr:port` other machine >"
).split(':')
remote_port = int(remote_port)
remote = remote_ip, remote_port
def read_chat(s):
global data
while True:
try:
data, addr = s.recvfrom(1024)
print(addr,'>', data)
except TimeoutError:
continue
reader = threading.Thread(target=read_chat, args=[sock])
reader.start()
while True:
line = input(">")
if ':' in line:
remote_ip, remote_port = input(
"input `addr:port` other machine >"
).split(':')
remote_port = int(remote_port)
remote = remote_ip, remote_port
else:
sock.sendto(line.encode(), remote)
Two such instances are started from the same network. also launched two different instances from different networks and then from the same network. Windows system firewall is disabled.
tried different combinations of sockets.
I have simple code that asks multiple inputs from user and sends it to the server but the server only recieves the first message. How can I make the server get rest of the messages?
Client:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1',8000))
for i in range(1,3):
message = input("Enter your message:")
s.send(message.encode())
s.close()
Server:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 8000))
s.listen(1)
print('ready')
while True:
c,addr = s.accept()
sentence = c.recv(1024)
print(sentence.decode())
c.close()
I think the problem is in the server.py line 7. It awaits to accept connection therefore does not wait to receive data.
For server.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 8000))
s.listen(1)
print('ready')
c,addr = s.accept()
while True:
sentence = c.recv(1024)
if sentence:
print(sentence.decode())
c.close()
For the client.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1',8000))
for i in range(1,3):
message = input("Enter your message:")
s.send(message.encode())
s.close()
I make client-sever app. It look like this:
client
import socket
host = '127.0.0.1'
port = 1338
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
while True:
st = input("Your message: ")
byt = st.encode()
s.send(byt)
server
import socket
host = ''
port = 1338
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
while True:
s.listen(5)
conn, addr = s.accept()
data = conn.recv(2000)
print(data.decode())
Problem is that only first message is display. How can I solve this problem?
The server receives data only once after accepting a connection from the client. In-order to receive continuously, you can have a while loop for receiving data from the client.
import socket
host = ''
port = 1338
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
while True:
s.listen(5)
conn, addr = s.accept()
condition = True
while condition:
data = conn.recv(2000)
if not data: break
print(data.decode())
So, the above code will receive data as long the user provides data. You can separate the data receiving part in a separate thread too.
As you have the client's connect outside the loop, you have to place the server's listen and accept also outside the loop, since the connection is to be established only once.
I'm leanring how sockets work and trying to do some simple things.
My client is NOT sending anything to the server, and the server will not receive anything. But the problem is that the server socket will be always waiting for nothing. I want it to do something else if there is no available coming data from the client side. The if statement does not help end its waiting.
Server.py:
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
hostname = socket.gethostname()
host = socket.gethostbyname(hostname)
port = 9090
server.bind((host, port))
server.listen(10)
con, addr = server.accept()
msg = con.recv(2048)
if not msg:
con.send('hello world'.encode('utf-8'))
con.close()
server.close()
else:
con.send('hi Client I received it'.encode('utf-8'))
con.close()
server.close()
Client.py:
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('192.155.11.79', 9090))
data = client.recv(2048).decode('utf-8')
print('From server side: ', data)
client.close()
I am a beginner in python socket programming. My question is, I have a TCP server in listen mode at that time client will send data to the server. But when my TCP server is unavailable at that I want a client to go and check for connection every time (something like try exception method with while loop).
I have tried tricks but that didn't work out, it gives o/p like connection refused when my TCP server is unavailable. Below is my code help me with same.
# client.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 2195
s.connect((host, 2195))
while 1:
try:
print "Try loop"
s.sendall("Welcome to Python\r\n")
print "Try loop2"
time.sleep(5)
except:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.close()
I have tried many solutions but below code works for me.
client.py
import socket
import time
while True:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
host = socket.gethostname()
port = 2195
try:
s.connect((host , port))
s.sendall("Welcome to Python\r\n")
except:
print "Error"
time.sleep(5)
s.close()