I've got this code at the moment, it's a simple socket server:
import socket
import time
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 9999
serversocket.bind((host, port))
serversocket.listen(5)
while True:
clientsocket,addr = serversocket.accept()
print(str(addr) + "connected")
test = "Package"
clientsocket.send(test.encode('utf-8'))
clientsocket.close()
I also made a client that gets the message. However, how do I make it so that when I type in the address of my socket on for example Chrome, it displays "Package". I have basic knowledge on handlers and such, but I can't find any DIY websocket tutorials on the internet.
I do not want to use for example tornado, I want to make a simple one myself
Thank you very much in advance!
Related
I've been recently introduced to the standard socket module in python, and have begun experimenting with it myself. However, upon sending my projects to friends, I've soon bumped into the problem that the programs have only local network reach.
Here's an example of what I've been working on- it's a simple program that connects a server to one client, then engages them in a simple chat loop indefinetly.
This program has been copied from this video tutorial, with some modifications:
https://www.youtube.com/watch?v=YwWfKitB8aA&t=1614s
(IP has been slightly modified for privacy purposes.)
SERVER:
import socket
HOST = '192.168.0.1'
PORT = 43218
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST, PORT))
server.listen()
commsocket, address = server.accept()
print(f"Connected to {address}")
while(True):
message = commsocket.recv(1024).decode("utf-8")
print(f"Message from client: {message}")
returnmessage = input("Type in message to send: ")
commsocket.send(returnmessage.encode('utf-8'))
CLIENT:
import socket
from time import sleep
HOST = '192.168.0.1'
PORT = 43218
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.connect((HOST, PORT))
while(True):
message = input("Type in message to send, then press enter: ")
server.send(message.encode('utf-8'))
print(f"Message from server {server.recv(1024).decode('utf-8')}")
Is it in any way possible to modify this so that anyone from outside my LAN (if possible, even to a global reach) can use this program as a client? If possible, with only the use of the vanilla socket module.
Thank you
The task is building two files client.py and server.py. I am able to connect the client to the server. The problem I encounter is when I trying to send a get request like client.send("bGET /suc.txt HTTP/1.1\r\nHost:127.0.0.1\r\n\r\n"), I do not how to return the file suc.txt to the client from the server side. The scene is a client request file from a server and what the server returns is the respond header and the requested file.
What I wrote so far :
Client:
import socket
target_host = "127.0.0.1"
target_port = 5050
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((target_host,target_port))
client.send("bGET /suc.txt HTTP/1.1\r\nHost:127.0.0.1\r\n\r\n")
response = client.recv(1024)
print(response.decode())
Server:
import socket
import threading
import urllib.request
HEADER = 64
PORT = 5050
HOST = socket.gethostbyname(socket.gethostname())
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST,PORT))
def handleClient(conn, addr):
print (f"[NEW CONNECTION {addr} connected. ")
connected = True
while connected:
conn.send()
def start():
server.listen()
while True:
conn, addr = server.accept()
thread = threading.Thread(target=handleClient, args=(conn,addr))
thread.start()
print(f"[ACTIVE CONNECTIONS] {threading.activeCount()} ")
print ("server is starting...")
start()
client.send("bGET /suc.txt HTTP/1.1\r\nHost:127.0.0.1\r\n\r\n")
The "b..." should be b"...", i.e. you want to specify a sequence of bytes and not a string with a b as first character.
I do not how to return the file suc.txt to the client from the server side
You basically ask very broadly how to read an HTTP request, extract information from it, create a proper response and send it. All what you code so far does is create a listener socket, so you are far away from your ultimate goal.
There are two major ways to tackle this: the easy one is to use a library like http.server to implement the complexity of HTTP for you. The documentation contains actual examples on how to do this and there are many more examples on the internet for this.
The harder option is to study the actual HTTP standard and implement everything yourself based on this standard. Expecting that somebody explains the complex standard here and describes how to implement it would be a too broad question.
I want to create a server-client chat program using python sockets. I was trying to connect server(me) and client(my friend) through the internet, but still I can't understand the way to do it. Please help me.
Server:
import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((my host, 12345))
s.listen(1)
conn, addr=s.accept()
while 1:
msg=input(">>")
conn.send(msg.encode())
print("Client:"+conn.recv(1024).decode())
Client:
import socket
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((my host, 12345))
while 1:
print("Server:"+s.recv(1024).decode())
msg=input(">>")
s.send(msg.encode())
I recommend using ngrok, it acts as a port forwarder without having to do it yourself. Download ngrok to your system32 folder and in your command prompt enter the following:
ngrok tcp %PORT%
This will create a TCP socket on localhost, ('0.0.0.0') so now you will have to do the following to your program:
SERVER:
s.bind(('0.0.0.0', %PORT%)) # The port you used for ngrok`
CLIENT:
s.connect(('NGROKHOSTIP', %NGROK FORWARDED PORT%))
The NGROKHOSTIP can be found with a domain to IP program. You can do this yourself with Python.
Also, sorry I couldn't explain this better, I'm new to stackoverflow.
I am working on a python program which will allow me to send and receive data between PCs. I have managed to get it to work in my local network and wanted to set it up to be able to connect from the internet. I opened the port 1234 in my router and used the local IP on the server.py and puclic IP on the client, but the server.py seems to not receive any data. What am I doing wrong here?
The example code is something like this (it works for local networks, but on separate PCs only, IP address, of course, is just an example and probably will not work for anyone else):
server.py:
import socket
import time
import pickle
IP = "192.168.1.69"
PORT = 1234
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((IP, PORT))
server_socket.listen()
print(f'Listening for connections on {IP}:{PORT}...')
client_socket, client_adress = server_socket.accept()
print(pickle.loads(client_socket.recv(1024)))
client_socket.send(pickle.dumps('DONE'))
time.sleep(1)
client_socket.send(pickle.dumps('boi'))
print(client_socket, client_adress)
client.py:
import socket
import pickle
import time
IP = "192.168.1.69"
PORT = 1234
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP, PORT))
client_socket.setblocking(False)
client_socket.send(pickle.dumps("NICE."))
time.sleep(1)
print(pickle.loads(client_socket.recv(1024)))
time.sleep(1)
print(pickle.loads(client_socket.recv(1024)))
Thank you.
How do I get a response from the server?
Client side:
#CLIENT
import socket
import time
host = "localhost"
port = 5454
data_c = input()
c = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
c.sendto(bytes(data_c, 'utf-8'),(host,port))
print( data_c )
print( c.recv(1024).decode('utf-8'))
SERVER side:
#SERVER
import socket
import time
host = "localhost"
port = 5454
data_s = "ACKNOWLEDGMENT"
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
print(s.recv(1024).decode('utf-8'))
I can send a message from the server that the client will receive, but can not seem to get communication (like an ACK.) to make it back to the server.
(yes UDP is not a good way to be doing this i'm pretty sure, but that was a specific for the project)
for question 1: to send the ACK, you could replicate what you have in the reverse direction.
Since UDP is connection-less you don't know beforehand you receive a packet where the packet will come from, so you have to use recvfrom to get both the packet and the peer (address/port) the packet came from. Then you have to use that address to send data back.
What you're doing now in your client (but what really looks like the server) in the loop is send the same data over and over to itself. Instead in the loop you should receive packets using the previously mentions recvfrom then send replies to the peer you received the packet from.
So something like the following pseudo code
while True:
peer = recvfrom(...)
sendto(..., peer)
After many attempts to get a simple acknowledgment reply from my server this did it.
Beyond literally starting completely over each round, the time.sleep(.1) function was the only missing key. It allowed the server and client both time to close the current socket connection so that there was not an error of trying to bind multiple bodies to a single location or something.
OSError: [WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted
Working result:
#SERVER
import socket
import time
host = "localhost"
port = 5454
data_s = "ACKNOWLEDGMENT"
while 1:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((host, port))
received = print("Client: " + s.recv(1024).decode('utf-8')) #waiting to receive
s.close
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
time.sleep(.1)
s.sendto(bytes(data_s, 'utf-8'),(host,port)) #sending acknowledgment
print("Server: " + data_s)
s.close # close out so that nothing sketchy happens
time.sleep(.1) # the delay keeps the binding from happening to quickly
Server Command Window:
>>>
Client: hello
Server: ACKNOWLEDGMENT
Client:
#CLIENT
import socket
import time
host = "localhost"
port = 5454
c = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while 1:
data_c = input("Client: ")
c = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
c.sendto(bytes(data_c, 'utf-8'),(host,port)) #send message
c.close
# time.sleep()
c = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
c.bind((host, port))
print("Server: " + c.recv(1024).decode('utf-8')) # waiting for acknowledgment
c.close
c = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
time.sleep(.1)
Client Command Window:
>>>
Client: hello
Client: hello
Server: ACKNOWLEDGMENT
I did finally remove the redundant input("Client: ") there at the top.
A special thanks #JoachimPileborg for helping, but I have to give it to the little guy just because it was the path I ended up taking.