Python3 Socket Programming - python-3.x

I am creating a software in Python3 and I need to Communicate with Whole World.
How I can create a socket over the wide area network instead of local area network!
Or Does socket programming works in such a way that client is in another network???
Plz I Need Answer as soon as possible!

Here is a example
import socket
HOSTNAME = "the host name"
PORT = xxxx
my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
my_socket.connect((HOST, PORT))
And I suggest you reed the Documentaion for waht you need.

Related

Does python ssl encrypt the data in both directions?

I implemented a TCP socket client/server for a service I want to run on a virtual machine.
Furthermore, I want to encrypt the data transfer in both directions using the python library ssl. Currently, my code looks like this:
Server:
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.set_ciphers('ECDHE-ECDSA-AES256-GCM-SHA384')
context.load_cert_chain(certfile="cert.pem", keyfile="prKey.pem")
tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcpsock.bind((ip, port))
ssocket = context.wrap_socket(tcpsock, server_side=True)
Client:
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
context.load_verify_locations("cert.pem")
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssock = context.wrap_socket(sock, server_hostname=server_ip)
I generated my private key + self-signed certificate with OpenSSL.
I recently met someone who seemed to know about encryption (I´m new to this topic), hence I asked him quite a lot about my code. He told me that TLS normally only encrypts traffic one way and that I needed mutual TLS, which is more complicated. Since he was not a python developer he could not give me specific advice for my code, so I searched on the internet and inside the SSL documentation.
I don´t know if this is an obvious/stupid question but I could not find a simple answer for if my server/client connection is encrypted from both sides.
I also used wireshark to track the traffic of my client/server:
I´m not sure how to interpret the output but every two lines the protocol says TLSv1.3 (in the dropdown description it says TLS 1.2 which should be correct regarding the chosen cipher) while in the other lines it says TCP. Does this mean that only one side uses TLS while the other side sends its data unencrypted?
Right now both (server and client) run on my localhost, later the server will be implemented on a virtual machine in my network.

How to send a message between 2 computers

I have looked into many tutorials and source code for pythons socket modal to try to send a simple string between two computers.
I have made my code work independently on the PCs, but have failed to get the code to run on both. Here is the code I am currently working with:
#server.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 1234))
s.listen(5)
while True:
# now our endpoint knows about the OTHER endpoint.
clientsocket, address = s.accept()
print(f"Connection from {address} has been established.")
clientsocket.send(bytes("Send test","utf-8"))
clientsocket.close()
#client.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 1234))
while True:
full_msg = ''
while True:
msg = s.recv(8)
if len(msg) <= 0:
break
full_msg += msg.decode("utf-8")
if len(full_msg) > 0:
print(full_msg)
I am running the client script on both computers, but when I run the script on the pc not running the server, I get error the connection refused error [#10061]. I am running python 3.7, one pc is a laptop connected via internet, and one is a desktop connected to a router via Ethernet cable.
If someone knows what I need to change to get the program to run correctly, it would be much appreciated.
I am a rookie in python but I have experience in networking. Your problem sounds like a network issue to me. Before you run your program, you have to make sure there is connectivity between the two computers as you mentioned a laptop in the internet. Best way to know is pinging to each other. Your problem sounds like a typical NAT (network address translation issue).
I think you didn't open your '1234' port in your firewall.
https://www.windowscentral.com/how-open-port-windows-firewall
If you are using windows, this link can help you

Python3: Is a write to UDP socket as file object even possible?

In Python3 I created a socket with s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) in order to send UDP to a certain destination in the network. Now the classical way would be to s.sendto(my_data, (ip, port)). But I would like to handle the socket as an io file object. Therefore I created one by f = s.makefile(mode='wb'). Now I can use f.write(my_data) to send data. But wait ... I never had to specify IP and port. Needless to say, the data does not arrive at the destination. With TCP there is no problem because with s.connect((ip, port)) I can specify ip and port before I create a file object.
Is it possible, and if yes how, to send UDP with a socket as file object?
okey...as I was writing the question it occurred to me that I could try calling s.connect((ip, port)) on the UDP socket although there is no connection to establish. Voilà it works. Maybe this helps somebody.

Why is my Socket Client not allowing the outgoing connection in python 3?

I have created a very simple UDP Socket client and server in python3.
I'm trying to send the simple message 'hello' to the server and I am getting the error:
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it
I'm not sure that it's actually the target machine's fault as the target machine is an AWS EC2 Ubuntu instance with 'All Traffic Allowed' configured with the security group.
I'm convinced it has to be some sort of outbound policy on my desktop computer...
Any help is appreciated.
Here is my code:
client.py
import socket
client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_sock.connect(('servers public ipv4 ip', 8089))
client_sock.send('hello'.encode())
server.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('localhost', 8089))
s.listen(5) #5 connections
while True:
conn, addr = s.accept()
buffer = conn.recv(64)
if len(buffer) > 0:
print(buffer.decode())
break
First, despite your repeated claims (in body and tags) that you are using UDP you are actually using TCP as can be seen from your use of SOCK_STREAM and accept.
s.bind(('localhost', 8089))
You explicitly bind the server to localhost. But localhost is only the loopback interface of the computer (127.0.0.1) which is not reachable from outside. If you want to accept connections from other systems you need to either bind to the IP address of the specific network interface or broadly to 0.0.0.0 - or simply use s.bind('',8089).

Basic UDP networking doesn't receive

I'm trying to learn UDP networking so I tried the simplest code to begin with. It's a python code client-server that works perfectly when I send data to localhost or to the LAN IP from the same computer, but it doesn't work when I try to send from my computer using the public IP, and also doesn't work from another computer using private network IP or public IP.
I did the port forwarding, created the input rules for windows firewall, turned off the router internal firewall, and it still doesn't work.
When I scan my port from canyouseeme.org or using netcat it says connection refused and port closed.
Maybe somebody can guess what is happening here or what may I do to succeed?
I write the code below in case it's needed.
Server:
import socket
UDP_IP = "0.0.0.0"
UDP_PORT = XXXX
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.bind((UDP_IP, UDP_PORT))
while True:
data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
message = data.decode()
print("received message:", message)
Client:
import socket
UDP_IP = "192.168.1.133"
UDP_PORT = XXXX
MESSAGE = "Hello, World!"
print("UDP target IP:", UDP_IP)
print("UDP target port:", UDP_PORT)
print("message:", MESSAGE)
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.sendto(MESSAGE.encode(), (UDP_IP, UDP_PORT))
Thanks in advance.
After some investigation I have found a partial solution. I'm posting an answer because it may help some people with similar problems, but it's not the best solution yet, so the issue is still there.
I found that there's no problem in communicating within a LAN if I completely disable the firewall in both computers. I don't know why the input rules or exceptions don't work.
For networking beyond the LAN I have tried successfully to use a virtual LAN (i.e. hamachi) and there's no necessity of port forwarding nor disabling the firewall. The bad thing about hamachi is that I don't control the protocol it uses, and I don't control the way of ensuring reliability.
For the applications I'm dealing with right now I probably have enough with this solution, but it would be interesting to know more.

Resources