I am currently using the socket library in python to send basic text from one computer to another on the same local network.
My problem is that due to me using different computers on multiple occasions the iPv4 which the client connects to changes each time .
Line 4 of the client code : client.connect(("172.16.0.34",8888))
This introduces a difficulty as I cant change the ip in the client code very easily.
My Question:
Is there possibly a way that the client can "scan" the network to see what ip is hosting a socket and obtain that ip to connect to them, allowing me to use any computer and have it still functioning?
Here is my code:
Client:
import socket
client = socket.socket()
try:
client.connect(("172.16.0.34",8888))
except:
print("Server not connected")
else:
print("Connect to server: ","localhost")
while True:
print("[Waiting for response...]")
print(client.recv(1024))
valid = False
while not valid:
try:
msg = str(input("Enter your message to send: "))
except:
print("Invalid input format")
else:
valid = True
to_send = msg.encode("UTF-8")
client.send(to_send)
Server:
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Socket created")
host = "0.0.0.0"
port = 8888
print(host)
try:
server.bind((host,port))
except:
print("Bind failed")
else:
print("Bind successful")
server.listen(5)
clientsocket = None
while True:
if clientsocket == None:
print("[Waiting for connection..]")
(clientsocket, address) = server.accept()
print("Client accepted from", address)
else:
print("[Waiting for response...]")
print(clientsocket.recv(1024))
valid = False
while not valid:
try:
msg = str(input("Enter your message to send: "))
except:
print("Invalid input format")
else:
valid = True
clientsocket.send(msg.encode("UTF-8"))
Related
#SOLVED#
It is solved when i disable Microsoft FireWall...
I want to make a basic multiplayer game using pygame and socket.
I created two scripts server.py and client.py .
I can send data from one pythonwindow to anotherwindow in the same computer but I want to send data to another window in another computer that connects the same internet connection.
How could it be possible ? Thank you
server.py
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ipv4 = socket.gethostbyname(socket.gethostname())
port = 1233
server_socket.bind((ipv4, port))
#Listens for new connections.
server_socket.listen(5)
#5 is backlog parameter that means while server is busy keep 5 connections.
# If sixth connection comes it will immediately be refused.
connection = True
while connection:
print("Server is waiting for connection.")
client_socket,addr = server_socket.accept()
print("client connected from {}".format(addr))
while True:
data = client_socket.recv(1024)
#Max 1024 bytes can be received and the max amount of bytes is given as parameter.
if not data or data.decode("utf-8") == "END":
connection = False
break
print("received from client : {a}".format(a = data.decode("utf-8")))
try:
client_socket.send(bytes("Hey client","utf-8"))
except:
print("Exited by the user")
client_socket.close()
server_socket.close()
client.py
import socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ipv4 = socket.gethostbyname(socket.gethostname())
port = 1233
print(ipv4)
#Connection of client to the server.
client_socket.connect((ipv4, port))
message = "Hey naber moruk nasilsin? Ben gayet iyiyim."
try :
while True:
client_socket.send(message.encode("utf-8"))
data = client_socket.recv(1024)
print(str(data))
more = input("Want to send more data to the server ? ('yes' or 'no')")
if more.lower() == "y":
message = input("Enter Payload")
else:
break
except KeyboardInterrupt:
print("Exited by the user")
client_socket.close()
Problem while making connection with server.
server side:
import socket
import threading
import sys
ip = "let ip address of server, cant type real one for security purposes, example: 1.2.3.4"
port = 9999
def make_socket(ip, port):
global server
try:
server = socket.socket()
server.bind((ip, port))
except:
make_socket(ip, port)
def handle_client(conn, addr):
print(f"Connected with {addr}\n")
connected = True
while connected:
msg = conn.recv(1024).decode("utf-8")
if msg == "exit()":
connected = False
if len(msg) > 0:
print(f"CLIENT: {msg}")
if connected:
msg = input("You: ")
if len(msg) > 0:
conn.send(msg.encode("utf-8"))
conn.close()
def make_connection():
server.listen(2)
while True:
conn, addr = server.accept()
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
print(f"ACTIVE CONNECTIONS:{threading.activeCount() - 1}")
print("SERVER INITIATED.")
make_socket(ip, port)
make_connection()
client side:
import socket
ip = "same address as written in server side, example: 1.2.3.4"
port = 9999
client = socket.socket()
client.connect((ip, port))
def send(msg):
message = msg.encode("utf-8")
client.send(message)
run = True
while run:
msg = input("You: ")
if msg == "exit()":
send(msg)
run = False
else:
send(msg)
print(f"Server: {client.recv(100).decode('utf-8')}")
It runs as expected in the same pc.
But when I am running client script and server script in 2 different pcs, they are not connecting. Even though the address is same. I have to type the ip address of server in server.bind and client.connect, right? They both should be same, right?
The IP address you pass to client.connect() should be the IP address of the computer where the server is running (if it's the same computer as where the client is running, you can just pass 127.0.0.1 as that address always means localhost). For the bind() call I recommend passing in '' (i.e. an empty string) as the address, so that your server will accept incoming connections from any active network interface. You only need to pass in an explicit IP address to bind() if you want limit incoming connections to only those coming through the local network card that is associated with the specified IP address.
After that I have connected to the server from input, how do I change my server in the chat?
I just updated the code with something that could work though it needs some more work, anyone?
def send(event=None): # event is passed by binders.
"""Handles sending of messages."""
global HOST
global PORT
global ADDR
msg = my_msg.get()
my_msg.set("") # Clears input field.
msg_list1 = msg.split()
try:
if msg_list1 [0] == "/connect":
try:
HOST = msg_list1[1]
PORT = int(msg_list1[2])
ADDR = (HOST,PORT)
client_socket.connect(ADDR)
receive_thread = Thread(target=receive)
receive_thread.start()
except TypeError:
msg_list_tk.insert(tt.END, "Error: please write '/connect ADDR PORT' to connect to server\n")
if msg_list1 [0] == "/connectnew":
HOST = msg_list1[1]
PORT = int(msg_list1[2])
ADDR = (HOST,PORT)
client_socket_2.connect(ADDR)
receive_thread = Thread(target=receive)
receive_thread.start()
except:
msg_list_tk.insert(tt.END, "Error: please write '/connect ADDR PORT' to connect to server\n")
elif msg == "/q":
root.quit()
client_socket.send(b"/q")
elif msg == "/disconnect":
client_socket.close()
else:
client_socket.send(bytes(msg, "utf8"))
except:
msg_list_tk.insert(tt.END, "Wrong input\n")
A TCP socket is only usable for a single TCP connection. If you want a second connection, you need to create a new socket and call connect() on that (i.e. you can't call connect() on your old socket a second time).
I'm trying to learn Network programming with Python language. In order that, I created a simple chat program with python. Now I want to encrypt communication between Server and Clients. How can I do that? The following code is my server code:
TcpSocket.bind(("0.0.0.0",8000))
TcpSocket.listen(2)
print("I'm waiting for a connection...!")
(client, (ip, port)) = TcpSocket.accept()
print("Connection recived from the {}".format(ip))
messageToClient = "You connected to the server sucessfuly.\n"
client.send(messageToClient.encode('ascii'))
dataRecived = "Message!"
while True:
dataRecived = client.recv(1024)
print("Client :", dataRecived)
print("Server :")
dataSend = raw_input()
client.send(str(dataSend) + "\n")
print("Connection has been closed.")
client.close()
print("Server has been shutdowned.")
TcpSocket.close()
def main():
try:
print("Server has started.")
connectionOrianted()
except :
print("Maybe connection terminated.")
finally:
print("Session has closed.")
if __name__ == "__main__": main()
And the following code is my client code.
#!/usr/bin/python3
import socket
import sys
from builtins import input
def main():
try:
serverHostNumber = input("Please enter the ip address of the server: \n")
serverPortNumber = input("Please enter the port of the server: \n")
# create a socket object
TcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connection to hostname on the port.
TcpSocket.connect((serverHostNumber, int(serverPortNumber)))
while True:
data = TcpSocket.recv(1024)
print("Server : ", data)
sendData = input("Client : ")
if sendData == "exit":
TcpSocket.close()
sys.exit()
TcpSocket.send(sendData.encode(encoding='ascii', errors='strict'))
except Exception as e:
print("The error: ", e)
TcpSocket.close()
sys.exit()
if __name__ == "__main__" : main()
I'm assuming you want to use the defacto standard for network encryption SSL (Secure Sockets Layer).
Client side is easy, basically you wrap your standard socket with an SSL socket, client side is built in so there's nothing special to install or import.
#!/usr/bin/python3
import socket
import sys
from builtins import input
def main():
try:
serverHostNumber = input("Please enter the ip address of the server: \n")
serverPortNumber = input("Please enter the port of the server: \n")
# create a socket object
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connection to hostname on the port.
sock.connect((serverHostNumber, int(serverPortNumber)))
TcpSocket = socket.ssl(sock)
while True:
data = TcpSocket.recv(1024)
print("Server : ", data)
sendData = input("Client : ")
if sendData == "exit":
TcpSocket.close()
sys.exit()
TcpSocket.send(sendData.encode(encoding='ascii', errors='strict'))
except Exception as e:
print("The error: ", e)
sys.exit()
if __name__ == "__main__" : main()
Server side is more difficult.
First you will need to install pyopenssl
After that you will need to generate a private key and a certificate (unless you already have one), this is pretty straight forward on linux, just run this from the command line:
openssl genrsa 1024 > key
openssl req -new -x509 -nodes -sha1 -days 365 -key key > cert
For Windows you will need to use one of these methods
Finally, once all the prerequisites are done SSl wraps sockets for the server side much like it does for the client side.
import socket
from OpenSSL import SSL
context = SSL.Context(SSL.SSLv23_METHOD)
context.use_privatekey_file('key')
context.use_certificate_file('cert')
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s = SSL.Connection(context, s)
s.bind(("0.0.0.0",8000))
s.listen(2)
print("I'm waiting for a connection...!")
(client, (ip, port)) = s.accept()
print("Connection recived from the {}".format(ip))
messageToClient = "You connected to the server sucessfuly.\n"
client.send(messageToClient.encode('ascii'))
dataRecived = "Message!"
while True:
dataRecived = client.recv(1024)
print("Client :", dataRecived)
print("Server :")
dataSend = raw_input()
client.send(str(dataSend) + "\n")
print("Connection has been closed.")
client.close()
print("Server has been shutdowned.")
s.close()
def main():
try:
print("Server has started.")
connectionOrianted()
except :
print("Maybe connection terminated.")
finally:
print("Session has closed.")
I haven't had the chance to test these scripts, but they should work. I hope this answers your question.
Hi i got a problem with my socket server or the client the problem is i can only send one message from the client to the server then the server stops receiving for some reason i want it to receive more then one.
Server.py
import socket
host = ''
port = 1010
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(1)
conn, addr = s.accept()
print ("Connection from", addr)
while True:
databytes = conn.recv(1024)
if not databytes:
break
data = databytes.decode('utf-8')
print("Recieved: "+(data))
if data == "dodo":
print("hejhej")
if data == "did":
response = ("Command recived")
conn.sendall(response.encode('utf-8'))
conn.close()
client.py
import socket
host = '127.0.0.1'
port = 1010
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
print("Connected to "+(host)+" on port "+str(port))
initialMessage = input("Send: ")
s.sendall(initialMessage.encode('utf-8'))
while True:
response = input("Send: ")
if response == "exit":
s.sendall(response.encode('utf-8'))
s.close()
There is nothing wrong with your code, but the LOGIC of it is wrong,
in the Client.py file and particularly in this loop:
while True:
response = input("Send: ")
if response == "exit":
s.sendall(response.encode('utf-8'))
This will not send to your Server side anything but string exit because of this:
if response == "exit":
So you are asking your Client.py script to only send anything the user inputs matching the string exit otherwise it will not send.
It will send anything at the beginning before this while loop since you wrote:
initialMessage = input("Send: ")
s.sendall(initialMessage.encode('utf-8'))
But after you are inside that while loop then you locked the s.sendall to only send exit string
You have to clean up your code logic.