I have three debian pc. one is the stun server and two others are clients.
I need to make those clients establish a peer to peer tcp connection.
For this case I'm using this github project.
This is the server side code:
#!/usr/bin/env python
import sys
import logging
import socket
import struct
import fcntl
import os
from util import *
logger = logging.getLogger()
clients = {}
def main(host='0.0.0.0', port=5005):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen(1)
s.settimeout(30)
while True:
try:
conn, addr = s.accept()
except socket.timeout:
continue
logger.info('connection address: %s', addr)
data = recv_msg(conn)
priv_addr = msg_to_addr(data)
send_msg(conn, addr_to_msg(addr))
data = recv_msg(conn)
data_addr = msg_to_addr(data)
if data_addr == addr:
logger.info('client reply matches')
clients[addr] = Client(conn, addr, priv_addr)
else:
logger.info('client reply did not match')
conn.close()
logger.info('server - received data: %s', data)
if len(clients) == 2:
(addr1, c1), (addr2, c2) = clients.items()
logger.info('server - send client info to: %s', c1.pub)
send_msg(c1.conn, c2.peer_msg())
logger.info('server - send client info to: %s', c2.pub)
send_msg(c2.conn, c1.peer_msg())
clients.pop(addr1)
clients.pop(addr2)
conn.close()
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')
main(*addr_from_args(sys.argv))
that have this util.py in its directory:
import struct
from collections import namedtuple
def addr_from_args(args, host='127.0.0.1', port=9999):
if len(args) >= 3:
host, port = args[1], int(args[2])
elif len(args) == 2:
host, port = host, int(args[1])
else:
host, port = host, port
return host, port
def msg_to_addr(data):
ip, port = data.decode('utf-8').strip().split(':')
return (ip, int(port))
def addr_to_msg(addr):
return '{}:{}'.format(addr[0], str(addr[1])).encode('utf-8')
def send_msg(sock, msg):
# Prefix each message with a 4-byte length (network byte order)
msg = struct.pack('>I', len(msg)) + msg
sock.sendall(msg)
def recvall(sock, n):
# Helper function to recv n bytes or return None if EOF is hit
data = b''
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data += packet
return data
def recv_msg(sock):
# Read message length and unpack it into an integer
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
# Read the message data
return recvall(sock, msglen)
class Client(namedtuple('Client', 'conn, pub, priv')):
def peer_msg(self):
return addr_to_msg(self.pub) + b'|' + addr_to_msg(self.priv)
and this is the clients' code with the same util.py but different ips
the ips in server side is the server's local ip and in client is server's public ip:
#!/usr/bin/env python
import sys
import logging
import socket
import struct
from threading import Event, Thread
from util import *
logger = logging.getLogger('client')
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')
STOP = Event()
def accept(port):
logger.info("accept %s", port)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
s.bind(('', port))
s.listen(1)
s.settimeout(5)
while not STOP.is_set():
try:
conn, addr = s.accept()
except socket.timeout:
continue
else:
logger.info("Accept %s connected!", port)
# STOP.set()
def connect(local_addr, addr):
logger.info("connect from %s to %s", local_addr, addr)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
s.bind(local_addr)
while not STOP.is_set():
try:
s.connect(addr)
except socket.error:
continue
# except Exception as exc:
# logger.exception("unexpected exception encountered")
# break
else:
logger.info("connected from %s to %s success!", local_addr, addr)
# STOP.set()
def main(host='54.187.46.146', port=5005):
sa = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sa.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sa.connect((host, port))
priv_addr = sa.getsockname()
send_msg(sa, addr_to_msg(priv_addr))
data = recv_msg(sa)
logger.info("client %s %s - received data: %s", priv_addr[0], priv_addr[1], data)
pub_addr = msg_to_addr(data)
send_msg(sa, addr_to_msg(pub_addr))
data = recv_msg(sa)
pubdata, privdata = data.split(b'|')
client_pub_addr = msg_to_addr(pubdata)
client_priv_addr = msg_to_addr(privdata)
logger.info(
"client public is %s and private is %s, peer public is %s private is %s",
pub_addr, priv_addr, client_pub_addr, client_priv_addr,
)
threads = {
'0_accept': Thread(target=accept, args=(priv_addr[1],)),
'1_accept': Thread(target=accept, args=(client_pub_addr[1],)),
'2_connect': Thread(target=connect, args=(priv_addr, client_pub_addr,)),
'3_connect': Thread(target=connect, args=(priv_addr, client_priv_addr,)),
}
for name in sorted(threads.keys()):
logger.info('start thread %s', name)
threads[name].start()
while threads:
keys = list(threads.keys())
for name in keys:
try:
threads[name].join(1)
except TimeoutError:
continue
if not threads[name].is_alive():
threads.pop(name)
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO, message='%(asctime)s %(message)s')
main(*addr_from_args(sys.argv))
So here is the problem: first of all i run the server and after that I run one of the clients and after 3 second i will run the other client and I always the normal log like:
2020-12-07 17:00:24,020 - client 172.20.10.5 36102 - received data: b'5.17.81.184:65333'
2020-12-07 17:00:24,473 - client public is ('5.17.81.184', 65333) and private is ('172.20.10.5', 36102), peer public is ('25.9.153.68', 52059) private is ('192.168.1.3', 45248)
2020-12-07 17:00:24,473 - start thread 0_accept
2020-12-07 17:00:24,474 - accept 36102
2020-12-07 17:00:24,474 - start thread 1_accept
2020-12-07 17:00:24,475 - accept 52059
2020-12-07 17:00:24,475 - start thread 2_connect
2020-12-07 17:00:24,476 - connect from ('172.20.10.5', 36102) to ('25.9.153.68', 52059)
2020-12-07 17:00:24,476 - start thread 3_connect
2020-12-07 17:00:24,477 - connect from ('172.20.10.5', 36102) to ('192.168.1.3', 45248)
but when take netstat i will see syn-sent, what should I do to take the syn-ack and after that ack?
does the code have problem? or what is there that i can't see?
Related
This program has both the ChatServer class and ChatClient class in the same file, and should be called in the terminal by --name=server --port=8800 for the server and --name=client1 --port=8800 for the client. The problem comes from the client class not being able to complete a try:
When running the program with server name, it seems to work fine. When it runs with client name, I get the output Failed to connect to chat server # port 8800.
You can find where this except statement lies.
import select
import socket
import sys
import signal
import _pickle as cPickle
import struct
import argparse
SERVER_HOST = 'localhost'
CHAT_SERVER_NAME = 'server'
# Some utilities
def send(channel, *args):
buffer = cPickle.dumps(args)
value = socket.htonl(len(buffer))
size = struct.pack("L", value)
channel.send(size)
channel.send(buffer)
def receive(channel):
size = struct.calcsize("L")
size = channel.recv(size)
try:
size = socket.ntohl(struct.unpack("L", size)[0])
except struct.error as e:
return ''
buf = ""
while len(buf) < size:
buf = channel.recv(size - len(buf))
return cPickle.loads(buf)[0]
class ChatServer(object):
def __init__(self, port, backlog=5):
self.clients = 0
self.clientmap = {}
self.outputs = []
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Enable re-using socket address
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server.bind((SERVER_HOST, port))
print('Server listening to port: %s...' % port)
self.server.listen(backlog)
# Catch keyboard interrupts
signal.signal(signal.SIGINT, self.sighandler)
def sighandler(self, signum, frame):
# Close the server
print("Shutting down server...")
# Close existing client sockets
for output in self.outputs:
output.close()
self.server.close()
def get_client_name(self,client):
info = self.clientmap[client]
host, name = info[0][0], info[1]
return '#'.join((name, host))
def run(self):
inputs = [self.server, sys.stdin]
self.outputs = []
running = True
while running:
try:
readable, writeable, exceptional = select.select(inputs, self.outputs, [])
except select.error as e:
break
for sock in readable:
if sock == self.server:
# handle the server socket
client, address = self.server.accept()
print("Chat Server: got connection %d from %s" % (client.fileno(), address))
# Read the login name
cname = receive(client).split('NAME: ')[1]
# Compute client name ad send back
self.clients += 1
send(client, 'CLIENT: ' + str(address[0]))
inputs.append(client)
self.clientmap[client] = (address, cname)
# Send joining information to other clients
msg = "\n(Connected: New client (%d) from %s)" % (self.clients, self.get_client_name(client))
for output in self.outputs:
send(output, msg)
self.outputs.append(client)
elif sock == sys.stdin:
# Handle standard input
junk = sys.stdin.readline()
running = False
else:
# Handle all other sockets
try:
data = receive(sock)
if data:
# Send as new client's message..
msg = '\n[' + self.get_client_name(sock) + ']>>' + data
# Send data to all except ourself
for output in self.outputs:
if output != sock:
send(output, msg)
else:
print("Chat server: %d hung up" % sock.fileno())
self.clients -= 1
sock.close()
inputs.remove(sock)
self.outputs.remove(sock)
# Sending client leaving info to others
msg = "\n(Now hung up: Client from %s" % self.get_client_name(sock)
for output in self.outputs:
send(output, msg)
except socket.error as e:
# Remove
inputs.remove(sock)
self.outputs.remove(sock)
self.server.close()
class ChatClient(object):
def __init__(self, name, port, host=SERVER_HOST):
self.name = name
self.connected = False
self.host = host
self.port = port
# Initial Prompt
self.prompt = '[' + '#'.join((name, socket.gethostname().split('.')[0])) + ']> '
# Connect to server at port
try:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((host, self.port))
print("Now connected to chat server# port %d" % self.port)
self.connected = True
# Send by name...
send(self.sock, 'NAME: ' + self.name)
data = receive(self.sock)
# Contains client address, set it
addr = data.split('CLIENT: ')[1]
self.prompt = '[' + '#'.join((self.name, addr)) + ']>'
except socket.error as e:
print("Failed to connect to chat server # port %d" % self.port)
sys.exit(1)
def run(self):
while self.connected:
try:
sys.stdout.write(self.prompt)
sys.stdout.flush()
# Wait for input from stdin and socket
readable, writable, exceptional = select.select([0, self.sock], [], [])
for sock in readable:
if sock == 0:
data = sys.stdin.readline().strip()
if data:
send(self.sock, data)
elif sock == self.sock:
data = receive(self.sock)
if not data:
print('Client shutting down')
self.connected = False
break
else:
sys.stdout.write(data + '\n')
sys.stdout.flush()
except KeyboardInterrupt:
print("Client interrupted")
self.sock.close()
break
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Socket Server Example with Select')
parser.add_argument('--name', action="store", dest="name", required=True)
parser.add_argument('--port', action="store", dest="port", type=int, required=True)
given_args = parser.parse_args()
port = given_args.port
name = given_args.name
if name == CHAT_SERVER_NAME:
server = ChatServer(port)
server.run()
else:
client = ChatClient(name=name, port=port)
client.run()
This is the code in serverside:
#!/usr/bin/env python
import sys
import logging
import socket
import struct
import fcntl
import os
from util import *
logger = logging.getLogger()
clients = {}
def main(host='**client public ip**', port=3443):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen(1)
s.settimeout(30)
while True:
try:
conn, addr = s.accept()
except socket.timeout:
continue
logger.info('connection address: %s', addr)
data = recv_msg(conn)
priv_addr = msg_to_addr(data)
send_msg(conn, addr_to_msg(addr))
data = recv_msg(conn)
data_addr = msg_to_addr(data)
if data_addr == addr:
logger.info('client reply matches')
clients[addr] = Client(conn, addr, priv_addr)
else:
logger.info('client reply did not match')
conn.close()
logger.info('server - received data: %s', data)
if len(clients) == 2:
(addr1, c1), (addr2, c2) = clients.items()
logger.info('server - send client info to: %s', c1.pub)
send_msg(c1.conn, c2.peer_msg())
logger.info('server - send client info to: %s', c2.pub)
send_msg(c2.conn, c1.peer_msg())
clients.pop(addr1)
clients.pop(addr2)
conn.close()
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')
main(*addr_from_args(sys.argv))
and this is clientside:
#!/usr/bin/env python
import sys
import logging
import socket
import struct
from threading import Event, Thread
from util import *
logger = logging.getLogger('client')
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')
STOP = Event()
def accept(port):
logger.info("accept %s", port)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
s.bind(('**server's public ip**', port))
s.listen(1)
s.settimeout(5)
while not STOP.is_set():
try:
conn, addr = s.accept()
except socket.timeout:
continue
else:
logger.info("Accept %s connected!", port)
# STOP.set()
def connect(local_addr, addr):
logger.info("connect from %s to %s", local_addr, addr)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
s.bind(local_addr)
while not STOP.is_set():
try:
s.connect(addr)
except socket.error:
continue
# except Exception as exc:
# logger.exception("unexpected exception encountered")
# break
else:
logger.info("connected from %s to %s success!", local_addr, addr)
# STOP.set()
def main(host='**client's local ip**', port=3443):
sa = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sa.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sa.connect((host, port))
priv_addr = sa.getsockname()
send_msg(sa, addr_to_msg(priv_addr))
data = recv_msg(sa)
logger.info("client %s %s - received data: %s", priv_addr[0], priv_addr[1], data)
pub_addr = msg_to_addr(data)
send_msg(sa, addr_to_msg(pub_addr))
data = recv_msg(sa)
pubdata, privdata = data.split(b'|')
client_pub_addr = msg_to_addr(pubdata)
client_priv_addr = msg_to_addr(privdata)
logger.info(
"client public is %s and private is %s, peer public is %s private is %s",
pub_addr, priv_addr, client_pub_addr, client_priv_addr,
)
threads = {
'0_accept': Thread(target=accept, args=(priv_addr[1],)),
'1_accept': Thread(target=accept, args=(client_pub_addr[1],)),
'2_connect': Thread(target=connect, args=(priv_addr, client_pub_addr,)),
'3_connect': Thread(target=connect, args=(priv_addr, client_priv_addr,)),
}
for name in sorted(threads.keys()):
logger.info('start thread %s', name)
threads[name].start()
while threads:
keys = list(threads.keys())
for name in keys:
try:
threads[name].join(1)
except TimeoutError:
continue
if not threads[name].is_alive():
threads.pop(name)
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO, message='%(asctime)s %(message)s')
main(*addr_from_args(sys.argv))
and this is the util.py code:
import struct
from collections import namedtuple
def addr_from_args(args, host='**server's local ip**', port=9999):
if len(args) >= 3:
host, port = args[1], int(args[2])
elif len(args) == 2:
host, port = host, int(args[1])
else:
host, port = host, port
return host, port
def msg_to_addr(data):
ip, port = data.decode('utf-8').strip().split(':')
return (ip, int(port))
def addr_to_msg(addr):
return '{}:{}'.format(addr[0], str(addr[1])).encode('utf-8')
def send_msg(sock, msg):
# Prefix each message with a 4-byte length (network byte order)
msg = struct.pack('>I', len(msg)) + msg
sock.sendall(msg)
def recvall(sock, n):
# Helper function to recv n bytes or return None if EOF is hit
data = b''
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data += packet
return data
def recv_msg(sock):
# Read message length and unpack it into an integer
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
# Read the message data
return recvall(sock, msglen)
class Client(namedtuple('Client', 'conn, pub, priv')):
def peer_msg(self):
return addr_to_msg(self.pub) + b'|' + addr_to_msg(self.priv)
and this is the error:
Traceback (most recent call last):
File "tcpclient.py", line 96, in <module>
main(*addr_from_args(sys.argv))
File "tcpclient.py", line 55, in main
sa.connect((host, port))
ConnectionRefusedError: [Errno 111] Connection refused
It's working in same network but in different one not!!
For adding more details I would say that we have one client and on server that wanna communicate to each other, client and server are both behind the nat and the server has webserver and client want to go to the webserver but because of the nat problem it can't. so we are trying to make a hole punching peer to peer connection to make client able to see the webserver.
we can't take any kind of ip static or commercial web service or isp or what ever that everyone say.
what's wrong with this code?
in util.py the ip should be public not private
import struct
from collections import namedtuple
def addr_from_args(args, host='**server's ip public**', port=9999):
if len(args) >= 3:
host, port = args[1], int(args[2])
elif len(args) == 2:
host, port = host, int(args[1])
else:
host, port = host, port
return host, port
def msg_to_addr(data):
ip, port = data.decode('utf-8').strip().split(':')
return (ip, int(port))
def addr_to_msg(addr):
return '{}:{}'.format(addr[0], str(addr[1])).encode('utf-8')
def send_msg(sock, msg):
# Prefix each message with a 4-byte length (network byte order)
msg = struct.pack('>I', len(msg)) + msg
sock.sendall(msg)
def recvall(sock, n):
# Helper function to recv n bytes or return None if EOF is hit
data = b''
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data += packet
return data
def recv_msg(sock):
# Read message length and unpack it into an integer
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
# Read the message data
return recvall(sock, msglen)
class Client(namedtuple('Client', 'conn, pub, priv')):
def peer_msg(self):
return addr_to_msg(self.pub) + b'|' + addr_to_msg(self.priv)
I'm writing a proxy with tcp connection that listens to multiple ports from a client and forward it to a server.
The problem is that the software hangs on the sock.accept.
Maybe I'm doing a messy logic here, but I need a client that connects to a PC, and that PC connects to another device. So I wrote that small proxy, and I get INVALID ARGUMENT ERROR in socket.accept()
import select
import socket
import threading
class Proxy(object):
def __init__(self, ip, ports):
self._ip = ip
self._sockets = []
self._proxy = {}
for port in ports:
self._proxy[port] = self.add_socket(port)
def add_socket(self, port=None):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if port:
# sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sock.bind(('0.0.0.0',port))
self._sockets.append(sock)
return sock
def get_client(self, src_sock, src_addr):
src_ip, src_port = src_addr
_, dst_port = src_sock.getsockname()
if src_ip == self._ip:
# got packet from device
dst_addr = ("10.8.8.210", dst_port)
else:
# got packet from client
dst_addr = self._ip, dst_port
print(">", src_port, dst_addr)
dst_sock = self._proxy[src_port]
return dst_sock, dst_addr
def run(self):
while True:
read_list, _, _ = select.select(self._sockets, [], [])
if read_list:
for sock in read_list:
try:
conn, addr = sock.accept()
data = conn.recvfrom(16*2024)
# print("got data from {} {}".format(sock, addr))
dst_sock, dst_addr = self.get_client(sock, addr)
# print("forwarding data from {} to {}".format(addr, dst_addr, len(data)))
dst_sock.sendto(data, dst_addr)
except:
raise # pass # print("no recipient for data")
for s in self._sockets:
s.close()
ports = [30001,30002,30003, 30070, 30071,30072,30075]
p = Proxy("192.168.2.10", ports)
p.run()
You have to call listen on the socket before accept:
adding sock.listen(1) to add_socket after bind
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('0.0.0.0', port))
sock.listen(1)
self._sockets.append(sock)
then allows you to call accept without the error. You may want to set the listen backlog to a greater number.
So I found this chat program on http://www.bogotobogo.com/python/python_network_programming_tcp_server_client_chat_server_chat_client_select.php
And I want to use this at my school for me and my friends, put I don't want to chat to be ex: [192.168.1.3] "Message". I want to be able to add another argument so it shows there name they input instead of Ip. It would be a little hard to have everyone using ips. Any suggestions?
Server Code:
# chat_server.py
import sys
import socket
import select
HOST = ''
SOCKET_LIST = []
RECV_BUFFER = 4096
PORT = 9009
def chat_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((HOST, PORT))
server_socket.listen(10)
# add server socket object to the list of readable connections
SOCKET_LIST.append(server_socket)
print "Chat server started on port " + str(PORT)
while 1:
# get the list sockets which are ready to be read through select
# 4th arg, time_out = 0 : poll and never block
ready_to_read,ready_to_write,in_error = select.select(SOCKET_LIST,[],[],0)
for sock in ready_to_read:
# a new connection request recieved
if sock == server_socket:
sockfd, addr = server_socket.accept()
SOCKET_LIST.append(sockfd)
print "Client (%s, %s) connected" % addr
broadcast(server_socket, sockfd, "[%s:%s] entered our chatting room\n" % addr)
# a message from a client, not a new connection
else:
# process data recieved from client,
try:
# receiving data from the socket.
data = sock.recv(RECV_BUFFER)
if data:
# there is something in the socket
broadcast(server_socket, sock, "\r" + '[' + str(sock.getpeername()) + '] ' + data)
else:
# remove the socket that's broken
if sock in SOCKET_LIST:
SOCKET_LIST.remove(sock)
# at this stage, no data means probably the connection has been broken
broadcast(server_socket, sock, "Client (%s, %s) is offline\n" % addr)
# exception
except:
broadcast(server_socket, sock, "Client (%s, %s) is offline\n" % addr)
continue
server_socket.close()
# broadcast chat messages to all connected clients
def broadcast (server_socket, sock, message):
for socket in SOCKET_LIST:
# send the message only to peer
if socket != server_socket and socket != sock :
try :
socket.send(message)
except :
# broken socket connection
socket.close()
# broken socket, remove it
if socket in SOCKET_LIST:
SOCKET_LIST.remove(socket)
if __name__ == "__main__":
sys.exit(chat_server())
Client Code:
# chat_client.py
import sys
import socket
import select
def chat_client():
if(len(sys.argv) < 3) :
print 'Usage : python chat_client.py hostname port'
sys.exit()
host = sys.argv[1]
port = int(sys.argv[2])
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)
# connect to remote host
try :
s.connect((host, port))
except :
print 'Unable to connect'
sys.exit()
print 'Connected to remote host. You can start sending messages'
sys.stdout.write('[Me] '); sys.stdout.flush()
while 1:
socket_list = [sys.stdin, s]
# Get the list sockets which are readable
ready_to_read,ready_to_write,in_error = select.select(socket_list , [], [])
for sock in ready_to_read:
if sock == s:
# incoming message from remote server, s
data = sock.recv(4096)
if not data :
print '\nDisconnected from chat server'
sys.exit()
else :
#print data
sys.stdout.write(data)
sys.stdout.write('[Me] '); sys.stdout.flush()
else :
# user entered a message
msg = sys.stdin.readline()
s.send(msg)
sys.stdout.write('[Me] '); sys.stdout.flush()
if __name__ == "__main__":
sys.exit(chat_client())
I want to connect computers what is not in my lan. I want to connect real ip.
My server Code
import json
import os
import select
import socket
import sys
import urllib
import urllib.request
from optparse import OptionParser
ip = json.loads(urllib.request.urlopen('http://httpbin.org/ip').read().decode("utf-8"))['origin']
print(ip)
def isAlive(ip):
ret = os.system("ping -o -c 3 -W 3000 " + ip)
if ret != 0:
return True
return False
HOST = socket.gethostname()
SOCKET_LIST = []
RECV_BUFFER = 1024
PORT = 1993
def chat_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.listen(10)
# add server socket object to the list of readable connections
SOCKET_LIST.append(server_socket)
print("Chat server started on port " + str(PORT), "on Host " + str(HOST))
print(SOCKET_LIST)
while True:
ready_to_read, ready_to_write, in_error = select.select(SOCKET_LIST, [], [], 0)
for sock in ready_to_read:
if sock == server_socket:
sockfd, addr = server_socket.accept()
SOCKET_LIST.append(sockfd)
print("Client (%s, %s) connected" % addr)
broadcast(server_socket, sockfd, "[%s:%s] entered our chatting room\n" % addr)
else:
try:
data = sock.recv(RECV_BUFFER)
recvString = data.decode("utf-8")
print(recvString)
if data:
broadcast(server_socket, sock, "\r" + '[' + str(sock.getpeername()) + '] ' + data)
else:
if sock in SOCKET_LIST:
SOCKET_LIST.remove(sock)
broadcast(server_socket, sock, "Client (%s, %s) is offline\n" % addr)
except:
broadcast(server_socket, sock, "Client (%s, %s) is offline\n" % addr)
continue
server_socket.close()
def broadcast(server_socket, sock, message):
for socket in SOCKET_LIST:
if socket != server_socket and socket != sock:
try:
socket.send(message)
except:
socket.close()
if socket in SOCKET_LIST:
SOCKET_LIST.remove(socket)
if __name__ == "__main__":
sys.exit(chat_server())
Connection Code
import socket
print(socket.getaddrinfo("localhost", 80, 0, 0, socket.SOL_TCP))
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Socket successfully created")
print(socket.gethostbyname(socket.gethostname()))
except socket.error as err:
print("socket creation failed with error %s" % (err))
port = 1993
host_ip = '193.140.109.2'
s.connect((host_ip, port))
while True:
getGet = input("Send Data: ")
s.sendall(bytearray(getGet, 'utf8'))
if getGet == '-':
s.close()
I wrote this code but I cannot connect my pc. I have some questions.
1- Is sockets only for lan connection ?
2- How can i connect diffrent computer ?
s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM, 0)
port = 1993
host_ip = 'fe80::d862:a887:2f4c:53d0%12'
Solved my problem.