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.
Related
Hi This is my first post here. I am making a chatroom in Python using sockets and I have written the code for the server and client side. I am successful in establishing a connection between the server and the clients but I can't send any messages. The client provides a password and username through terminal and the server check if the password is correct and only then the client can send messages. I have not yet implemented the password check yet but the messages are still not being sent. I have made sure I am encoding and decoding correctly. I have also implemented threading to allow multiple users. Here is the server side code:
import socket
import threading
import sys
#TODO: Implement all code for your server here
#usernames = []
def broadcast(message):
for client in clients:
client.send(message)
def handle_client(client_socket, client_address):
try:
password = client_socket.recv(1024).decode()
username = client_socket.recv(1024).decode()
print("user: " + username)
clients.append(client_socket)
while True:
message = username + " joined the chatroom"
print(message)
broadcast(message.encode())
message = client_socket.recv(1024).decode()
if (message != ":Exit"):
print(f"{username}: {message}")
broadcast(message.encode())
else:
print(f"{username} left the chatroom")
clients.remove(client_socket)
client_socket.close()
message = username + " left the chatroom"
broadcast(message.encode())
break
except:
client_socket.close()
def receive():
while True:
client_socket, client_address = server.accept()
print(client_socket)
client_thread = threading.Thread(target=handle_client, args=(client_socket, client_address))
client_thread.start()
# Use sys.stdout.flush() after print statemtents
if __name__ == "__main__":
HOST = '127.0.0.1'
#PORT = int(sys.argv[1])
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST, 10001))
server.listen(5)
clients = []
print("server is listening")
receive()
Here is the client side:
import socket
import threading
import sys
#TODO: Implement a client that connects to your server to chat with other clients here
HOST = '127.0.0.1'
#PORT = int(sys.argv[1])
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((HOST, 10001))
username = sys.argv[1]
password = sys.argv[2]
client_socket.send(password.encode())
client_socket.send(username.encode())
reply = client_socket.recv(1024).decode()
print(reply)
def receive():
while True:
try:
message = client_socket.recv(1024).decode()
if message:
print(message)
except:
continue
def write():
while True:
message = input()
if message == ":Exit":
client_socket.send(message.encode())
client_socket.close()
break
else:
client_socket.send(message.encode())
receive_thread = threading.Thread(target=receive)
receive_thread.start()
write_thread = threading.Thread(target=write)
write_thread.start()
# Use sys.stdout.flush() after print statemtents
if __name__ == "__main__":
pass
I have tried asking my TAs but they were of no help :(.
It looks like you are taking the second and third arguments instead of first and second. Thus if you do not pass 3 arguments with the third being the password then the client will not have a password to send.
Can you help me with the program now the problem is that when I enter localhost my program cannot find the open port or the closed one, if you really want to help me and you know how to solve it or fix it, please just compile my code separately just for me right now the program for some reason can’t get to receive a message from the host, I searched the entire Internet and can’t find anywhere the scanner has multiple UDP ports
import socket
import sys
# Ask for input
remoteServer = raw_input('Enter a remote host to scan: ')
remoteServerIP = socket.gethostbyname(remoteServer)
print( "-" * 60)
print ('Please wait, scanning remote host', remoteServerIP)
print( "-" * 60)
for port in range(1,1025):
try:
sock=socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
sock.sendto('hello',(remoteServerIP,port))
#sock.settimeout(1)
data, address = sock.recvfrom(1024)
if data != None:
print ('Port {}: Open'.format(port))
else:
print ('Port {}: Closed'.format(port))
sock.close()
except socket.error as sock_err:
if(sock_err.errno == socket.errno.ECONNREFUSED):
print sock_err('Connection refused')
except socket.gaierror:
print 'Hostname could not be resolved. Exiting'
except socket.error:
print "Couldn't connect to server"
except KeyboardInterrupt:
print 'You pressed Ctrl+C'
Need to use ICMP packet.For the program to work, you need to enter python
I publish my code because the answer to this question is practically nonexistent and the task is actually difficult.
import socket
import sys
import subprocess
def getServiceName(port, proto):
try:
name = socket.getservbyport(int(port), proto)
except:
return None
return name
UDP_IP = sys.argv[1]
for RPORT in range(int(sys.argv[2]), int(sys.argv[3])):
MESSAGE = "ping"
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
if client == -1:
print("udp socket creation failed")
sock1 = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
if sock1 == -1:
print("icmp socket creation failed")
try:
client.sendto(MESSAGE.encode('utf_8'), (UDP_IP, RPORT))
sock1.settimeout(1)
data, addr = sock1.recvfrom(1024)
except socket.timeout:
serv = getServiceName(RPORT, 'udp')
if not serv:
pass
else:
print('Port {}: Open'.format(RPORT))
except socket.error as sock_err:
if (sock_err.errno == socket.errno.ECONNREFUSED):
print(sock_err('Connection refused'))
client.close()
sock1.close()
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"))
I amusing a client to send a message to a python server.
client side: client.send("1")
Server side:
d=clientsocket.recv(1024)
if (d=="1"):
print(" Correct value")
It won't print correct value. I know the error at recv as I don't know how it works. Could anyone please help me to solve this matter.
You just need simple modification to work it correctly:-
in client correct like below:-
client.send("1".encode())
in server correct like below:-
d=clientsocket.recv(1024).decode()
if (d=="1"):
print(" Correct value")
I have created one client and server for you which is working fine in Python 3.4. Please try and check:
Here is your server
import socket
import sys
HOST = "localhost"
PORT = 8000
print("Creating socket...")
sc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Binding socket...")
try:
sc.bind((HOST, PORT))
except socket.error as err:
print("Error binding socket, {}, {}".format(err[0], err[1]))
print("bound Successful")
# Configure below how many client you want that server can listen to simultaneously
sc.listen(2)
print("Server is listening on {}:{}".format(HOST, PORT))
while True:
conn, addr = sc.accept()
print("Connection from: " + str(addr))
print("Receiving data from client\n")
data = conn.recv(1024).decode()
print("Client says :" + data)
if(data == "2"):
print(" Ooh you are killing me with value :" + data)
conn.sendall(str.encode("\n I am server and you killed me with :" + data))
break;
elif(data == "1"):
print(" Correct value :" + data)
conn.sendall(str.encode("\n I am server and you hit me with correct value:" + data))
else:
print(" You are sending a wrong value :" + data)
conn.sendall(str.encode("\n I am server and you hit me with wrong value :" + data))
sc.close()
and now your client is here:-
import socket
import sys
HOST = "localhost"
PORT = 8000
print("creating socket")
sc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Connecting to host")
try:
sc.connect((HOST, PORT))
except socket.error as err:
print("Error: could not connect to host, {}, {}".format(err[0], err[1]))
sys.exit()
print("Connection established to host")
message = "1" # Run client 3 times with value message = '1' and '5' and '2'
sc.send(message.encode())
data = sc.recv(1024).decode()
print("Server response is : " + data)
sc.close()
I am trying to write a simple client-server program using python (not python3) and whenever I type a message to send it gives me various errors such as:
File "", line 1
hello my name is darp
^
SyntaxError: invalid syntax
OR
File "", line 1, in
NameError: name 'hello' is not defined
OR
File "", line 1
hello world
^
SyntaxError: unexpected EOF while parsing
Here is the server code:
import socket
def Main():
host = socket.gethostname()
port = 5000
s = socket.socket()
s.bind((host, port))
s.listen(1)
c, addr = s.accept()
print("Connection from: "+str(addr))
while True:
data = c.recv(1024).decode('utf-8')
if not data:
break
print("From connected user: "+data)
data = data.upper()
print("Sending: "+data)
c.send(data.encode('utf-8'))
c.close()
if __name__ == '__main__':
Main()
AND here is the client code
import socket
def Main():
host = socket.gethostname()
port = 5000
s = socket.socket()
s.connect((host, port))
message = input("-> ")
while message != 'q':
s.send(message.encode('utf-8'))
data = s.recv(1024).decode('utf-8')
print("Recieved from server: " + data)
message = input("-> ")
s.close()
if __name__ == '__main__':
Main()
Even though I can create this connection, the problem occurs after I type the message. Any help would be appreciated, thanks!
In Python2 use raw_input instead of input.
You should use the raw_input instead of input since raw_input will capture your input and convert it to the proper type. When using input you should add quotes around the input.
You can check this in the python docs: https://docs.python.org/2/library/functions.html#raw_input
As far as the code is concerned, the only change you need to make here is in server code. Replace c.close() with s.close() as c is a connection variable whereas s is the socket of server according to your code.
I have made your code run, after making the change it runs as expected.I executed it in Python 3.
The server code is here:
import socket
def Main():
host = "127.0.0.1" # supply different hostname instead of socket.gethostname()
port = 5000
s = socket.socket()
s.bind((host, port))
s.listen(1)
c, addr = s.accept()
print("Connection from: "+str(addr))
while True:
data = c.recv(1024).decode('utf-8')
if not data:
break
print("From connected user: "+data)
data = data.upper()
print("Sending: "+data)
c.send(data.encode('utf-8'))
s.close() # it is s which indicates socket
if __name__ == '__main__':
Main()
And the client code is as given by you:
import socket
def Main():
# here, client is using the hostname whereas you need to give different
# hostname for the server (127.0.0.1 for example) otherwise the code doesn't
# work.You can do the reverse as well.
host = socket.gethostname()
port = 5000
s = socket.socket()
s.connect((host, port))
message = input("-> ")
while message != 'q':
s.send(message.encode('utf-8'))
data = s.recv(1024).decode('utf-8')
print("Recieved from server: " + data)
message = input("-> ")
s.close()
if __name__ == '__main__':
Main()