I'm creating a local client-server game on Python using sockets where a server is hosted on the local network and the clients on the network can connect to the server if they have the server's IP address. It's not a dedicated server so it just runs on another thread on a client's computer. Currently, the client has to manually enter the IP address of the server to connect to it. I want the client to be able to search the network for avaialble servers join, but i'm not sure how to get the server to broadcast it's availability.
This is the server-side script:
totalConnections = 0
port = 5555
host=socket.gethostname()
IP = socket.gethostbyname(host) #this just fetches the computer's IP address so the server can use it
server = IP
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.bind((server, port))
except socket.error as e:
str(e)
s.listen(2)
print("Waiting for a connection, Server Started")
while True:
conn, addr = s.accept()
print("Connected to:", addr)
totalConnections += 1
start_new_thread(threaded_client, (conn, currentPlayer))
currentPlayer += 1
def threaded_client(conn, player):
conn.send(pickle.dumps(all_data[player])) # sends player data to client
While True:
conn.sendall(pickle.dumps(reply))
This is the client-side:
class Network:
def __init__(self,ip):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server = ip
self.port = 5555
self.addr = (self.server, self.port)
self.p = self.connect()
def getP(self):
return self.p
def connect(self):
try:
self.client.connect(self.addr)
return pickle.loads(self.client.recv(2048*3))
except:
pass
def send(self, data):
try:
self.client.send(pickle.dumps(data))
return pickle.loads(self.client.recv(2048*3))
except socket.error as e:
print(e)
I found the solution using multicasting on a specific UDP port where all the clients connect to so the data can be shared amongst them : https://pymotw.com/2/socket/multicast.html
Related
I have setup a tcp socket between a client and a server, very basic. Client side:
#!/usr/bin/env python3
import socket
# create a socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# get local machine name
host = "81.88.95.250"
port = 25000
# connection to hostname on the port.
s.connect((host, port))
# Receive no more than 1024 bytes
msg = s.recv(1024)
s.close()
print (msg.decode('ascii'))
server side:
#!/usr/bin/env python3
import socket
# create a socket object
serversocket = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
# get local machine name
host = socket.gethostname()
port = 25000
# bind to the port
serversocket.bind((host, port))
# queue up to 5 requests
serversocket.listen(5)
while True:
# establish a connection
clientsocket,addr = serversocket.accept()
print("Got a connection from %s" % str(addr))
msg = 'Thank you for connecting'+ "\r\n"
clientsocket.send(msg.encode('ascii'))
clientsocket.close()
My target is to send notification from client to server, and that's easy. The difficult part is that I also need in some circumstances to start the connection from the server and to send a command to the client and this must be executed as soon as it is received, so I cannot setup a periodic "poll". But I'm quite confused on this part, because the client is behind a NAT, not exposed with a public IP.
I try to transmit an image from a client to the server,
but it only worked for connection but sending image.
This is the code for the client:
import socket
host = '10.10.40.22'
port = 8888
address = (host, port)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
#connect to the server
s.connect(address)
print('start send image')
with open('doge.png', 'rb') as imgfile:
while True:
imgData = imgfile.readline(1024)
if not imgData:
break
s.send(imgData)
print('end')
and here is the code for the server:
host = '10.10.40.22'
port = 8888
address = (host, port)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(address)
s.listen(1)
print('wait for connection...')
conn, addr = s.accept()
#start to receive picture
with open('Pictures/doge.png', 'wb') as imgfile:
while True:
img_data = conn.recv(1024)
if not img_data:
break
imgfile.write(img_data)
print('writing ...')
conn.close()
s.close()
print('end')
notice that I print a debug message in the code of server that
if it writes any bytes into the image then print the message 'writing'
how can I do now?
Hello I am pretty much new to socket and I was trying to make a connection inside my local computer using socket.
this is the server
import socket
def server():
host = socket.gethostname() # get local machine name
port = 8080 # Make sure it's within the > 1024 $$ <65535 range
s = socket.socket()
s.bind(('192.168.56.1', port))
s.listen(1)
client_socket, adress = s.accept()
print("Connection from: " + str(adress))
while True:
data = s.recv(1024).decode('utf-8')
if not data:
breakpoint
print('From online user: ' + data)
data = data.upper()
s.send(data.encode('utf-8'))
s.close()
if __name__ == '__main__':
server()
and this is the client
import socket
def client():
host = socket.gethostname() # get local machine name
port = 8080 # Make sure it's within the > 1024 $$ <65535 range
s = socket.socket()
s.connect(("192.168.56.1", port))
message = input('-> ')
while message != 'q':
s.send(message.encode('utf-8'))
data = s.recv(1024).decode('utf-8')
print('Received from server: ' + data)
message = input('==> ')
s.close()
if __name__ == '__main__':
client()
I know there are useless lines in there but I will clean it up after I finish my connection .
In file transfer server-client program I want to access my server from html webpage and for that I'm using flask. But I can't connect flask with file transfer server to send and receive data. So what are the ways to access my file transfer server from flask server?
I tried to use TCP sockets for connection between flask and file transfer server but it ended up having error in connection
#FLASK SERVER
from flask import Flask, flash, redirect, render_template, request, session, abort
import sqlite3
import socket
app = Flask(__name__)
#app.route('/list',methods = ['POST', 'GET'])
def list():
socket_create()
socket_connect()
db_conn = sqlite3.connect('Backup_File.db')
if request.method == 'POST':
cursor = db_conn.execute('SELECT id, Mac_address, port_number from Client_List')
rows = cursor.fetchall()
for row in rows:
print("ID:",row[0])
print("Mac Address:",row[1])
print("Port number:",row[2])
return render_template('list.html',rows = rows)
#app.route('/clientAccess',methods = ['POST', 'GET'])
def clientAccess():
if request.method == 'POST':
return render_template('clientAccess.html')
#Connect to a server
# Create a socket
def socket_create():
try:
global host
global port
global source_port
global s
host = '192.168.0.30'
port = 9993
source_port = 9000
s = socket.socket()
except socket.error as msg:
print("Socket creation error: " + str(msg))
# Connect to a remote socket
def socket_connect():
try:
global host
global port
global source_port
global s
os.system("freeport 9000")
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('0.0.0.0', 9000))
s.connect((host, 9993))
except socket.error as msg:
print("Socket connection error: " + str(msg))
if __name__ == '__main__':
app.debug = True
app.run(host = '0.0.0.0',port=5005)
I expect the output that sending 'list' from flask server, the file transfer server should receive 'list' as string
I wrote a basic server-client scripts using sockets, and everything works fine on my LAN, but it doesnt work when im trying to connect to the client thats not in my LAN. I also port forwarded these ports
this is server
###SERVER####
def ChatConnection():
print('Waiting for a connection...\n')
SOCKET = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
SOCKET.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
HOST = ''
PORT = 8989
SOCKET.bind((HOST, PORT))
SOCKET.listen(1)
CONN, ADDR = SOCKET.accept()
print('You can now chat')
while True:
MSG = str(input('\n[YOU]> '))
while not MSG: MSG = str(input('\n[YOU]> '))
CONN.send(MSG.encode())
print('\nAwaiting reply...')
REPLY = CONN.recv(4096).decode()
CONN.close()
this is client
###CLIENT###
def ChatConnection():
print('Waiting for a connection...\n')
while True:
try:
HOST = SERVER EXTERNAL IP
PORT = 8989
SOCKET = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
SOCKET.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
SOCKET.connect((HOST, PORT))
print('You can now chat with server')
print('\nWaiting for server...')
while True:
REPLY = SOCKET.recv(4096)
print('\n[USER]> %s'%REPLY.decode())
MSG = str(input('\n[YOU]> '))
while not MSG: MSG = str(input('\n[YOU]> '))
SOCKET.send(MSG.encode())
print('\nAwaiting reply...')
SOCKET.close()
except Exception: pass
what i need to do so this will work on the WAN?
Make sure that port forward WORKS, to check this run your program and try running a port scan on your public IP.Port scanning tool
Try to change the HOST to 0.0.0.0.
If that didn't work go to CMD and write netstat -a while your script is running.
Search for the port you are listening on and make sure the IP is 0.0.0.0.
If the IP is 0.0.0.0 then try to turn off your Firewall.