i wanted to use a website to send some commands to a client app but in my host i can just access to ports 80 and 443 is it possible that i make socket programming with these ports?
i have tried my code on some ports like 8889 and but these are not available on my host
def send_to_client(key)://///the function on website that sends data to client
HOST = '10.42.0.158' # The server's hostname or IP address
PORT = 8889 # The port used by the server
connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connection.connect((HOST, PORT))
print("problem with socket")
# old = termios.tcgetattr(sys.stdin)
tty.setcbreak(sys.stdin.fileno())
try:
/////if key is ok send it to client app
connection.sendall(key)
return key + " sent succesfully"
else:
return "not proper input"
# key = sys.stdin.read(1)
finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old)
def recv_data()://///the function on client app that receive data from website
global data
#now keep talking with the client
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print ('Connected with ' + addr[0] + ':' + str(addr[1]))
while True:
d = conn.recv(1024).strip().decode('utf-8')
data = d
break
i want to know that is it possible that use port 80 to do this socket programming app
Related
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.
How can I create a socket server, and access it from another network\country? I create a server using java. I want to connect the server from another network (like a hotel's wi-fi)
How can I do that?
My python server:
def start():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((socket.gethostname(), 2201))
print("Waiting for connection...\n")
while True:
server.listen()
(client, (ipNum, portNum)) = server.accept()
message = str(client.recv(32).decode())
if(message != ""):
print("Client: " + message)
Command(message.lower())
print("Server: " + BackMessage)
else:
time.sleep(0.05)
start() # Start the server
Python client:
import socket
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 2001 # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
data = s.recv(1024)
print('Received', repr(data))
It's not working when I switch connections only when I'm in the same network with the server. How can I make it work?
My reputation is not enough to add a comment, so I put an answer here.
If server locate in a local area network, it cannot be found be a client in another local area network.
You should put the server at the WAN(Wide Area Network) or use NAT(Network Address Translation) + nat traversal.
I know this topic is not new. There is various information out there although, the robust solution is not presented (at least I did not found). I have a P2P daemon written in python3 and the last element on the pie is to connect two clients behind the NAT via TCP. My references for this topic:
https://bford.info/pub/net/p2pnat/
How to make 2 clients connect each other directly, after having both connected a meeting-point server?
Problems with TCP hole punching
What I have done so far:
SERVER:
#!/usr/bin/env python3
import threading
import socket
MY_AS_SERVER_PORT = 9001
TIMEOUT = 120.0
BUFFER_SIZE = 4096
def get_my_local_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
# doesn't even have to be reachable
s.connect(('10.255.255.255', 1))
IP = s.getsockname()[0]
except Exception:
IP = '127.0.0.1'
finally:
s.close()
return bytes(IP, encoding='utf-8')
def wait_for_msg(new_connection, client_address):
while True:
try:
packet = new_connection.recv(BUFFER_SIZE)
if packet:
msg_from_client = packet.decode('utf-8')
client_connected_from_ip = client_address[0]
client_connected_from_port = client_address[1]
print("We have a client. Client advertised his local IP as:", msg_from_client)
print(f"Although, our connection is from: [{client_connected_from_ip}]:{client_connected_from_port}")
msg_back = bytes("SERVER registered your data. Your local IP is: " + str(msg_from_client) + " You are connecting to the server FROM: " + str(client_connected_from_ip) + ":" + str(client_connected_from_port), encoding='utf-8')
new_connection.sendall(msg_back)
break
except ConnectionResetError:
break
except OSError:
break
def server():
sock = socket.socket()
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
sock.bind((get_my_local_ip().decode('utf-8'), MY_AS_SERVER_PORT))
sock.listen(8)
sock.settimeout(TIMEOUT)
while True:
try:
new_connection, client_address = sock.accept()
if new_connection:
threading.Thread(target=wait_for_msg, args=(new_connection,client_address,)).start()
# print("connected!")
# print("")
# print(new_connection)
# print("")
# print(client_address)
msg = bytes("Greetings! This message came from SERVER as message back!", encoding='utf-8')
new_connection.sendall(msg)
except socket.timeout:
pass
if __name__ == '__main__':
server()
CLIENT:
#!/usr/bin/python3
import sys
import socket
import time
import threading
SERVER_IP = '1.2.3.4'
SERVER_PORT = 9001
# We don't want to establish a connection with a static port. Let the OS pick a random empty one.
#MY_AS_CLIENT_PORT = 8510
TIMEOUT = 3
BUFFER_SIZE = 4096
def get_my_local_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
# doesn't even have to be reachable
s.connect(('10.255.255.255', 1))
IP = s.getsockname()[0]
except Exception:
IP = '127.0.0.1'
finally:
s.close()
return bytes(IP, encoding='utf-8')
def constantly_try_to_connect(sock):
while True:
try:
sock.connect((SERVER_IP, SERVER_PORT))
except ConnectionRefusedError:
print(f"Can't connect to the SERVER IP [{SERVER_IP}]:{SERVER_PORT} - does the server alive? Sleeping for a while...")
time.sleep(1)
except OSError:
#print("Already connected to the server. Kill current session to reconnect...")
pass
def client():
sock = socket.socket()
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
#sock.bind((get_my_local_ip().decode('utf-8'), MY_AS_CLIENT_PORT))
sock.settimeout(TIMEOUT)
threading.Thread(target=constantly_try_to_connect, args=(sock,)).start()
while True:
try:
packet = sock.recv(BUFFER_SIZE)
if packet:
print(packet)
sock.sendall(get_my_local_ip())
except OSError:
pass
if __name__ == '__main__':
client()
Now the current code results:
./tcphole_server.py
We have a client. Client advertised his local IP as: 10.10.10.50
Although, our connection is from: [89.22.11.50]:32928
We have a client. Client advertised his local IP as: 192.168.1.20
Although, our connection is from: [78.88.77.66]:51928
./tcphole_client1.py
b'Greetings! This message came from SERVER as message back!'
b'SERVER registered your data. Your local IP is: 192.168.1.20 You are connecting to the server FROM: 89.22.11.50:32928'
./tcphole_client2.py
b'Greetings! This message came from SERVER as message back!'
b'SERVER registered your data. Your local IP is: 10.10.10.50 You are connecting to the server FROM: 78.88.77.66:51928'
As you can see the server has all information to connect two clients. We can send details about the other peer individually through the current server-client connection.
Now two questions remain in my head:
Assuming the SERVER sends information about CLIENT 1 and CLIENT 2 for each of the peers. And now the CLIENTS starts connecting like [89.22.11.50]:32928 <> [78.88.77.66]:51928 Does the SERVER should close the current connections with the CLIENTS?
How the CLIENT Router behaves? I assume it expecting the same EXTERNAL SERVER SRC IP [1.2.3.4], instead gets one of the CLIENTS EXT IP for instance [89.22.11.50] or [78.88.77.66]?
This is messier than I thought. Any help to move forward appreciated. Hope this would help other Devs/DevOps too.
Finally found the expected behavior! Don't want to give too much code here but I hope after this you will understand the basics of how to implement it. Best to have a separate file in each of the client's folder - nearby ./tcphole_client1.py and ./tcphole_client2.py. We need to connect fast after we initiated sessions with the SERVER. Now for instance:
./tcphole_client_connector1.py 32928 51928
./tcphole_client_connector2.py 51928 32928
Remember? We need to connect to the same ports as we initiated with SERVER:
[89.22.11.50]:32928 <> [78.88.77.66]:51928
The first port is needed to bind the socket (OUR). With the second port, we are trying to connect to the CLIENT. The other CLIENT doing the same procedure except it binds to his port and connects to yours bound port. If the ROUTER still has an active connection - SUCCESS.
I'm new to socket programming but with the help of a tutorial i wrote a simple Server and Client. It works
if i connect to the server from the same device the server runs on but if i try to connect from another device it doesn't work. I tried to disable my firewall and some other tips on similar questions but it doesn't work.
This is the Server:
import threading
import socket
import time
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOSTNAME = socket.gethostbyname(socket.gethostname())
PORT = 50000
print(HOSTNAME, PORT)
s.bind((HOSTNAME, PORT))
s.listen()
clientList = []
def func():
while True:
conn, addr = s.accept()
conn.send(str.encode("Connected"))
print(addr, " connected")
clientList.append(conn)
t = threading.Thread(target=func2, args=(conn, addr,)).start()
def func2(x, y):
print(bytes.decode(x.recv(1024)))
x.send(str.encode("Type your name"))
y = bytes.decode(x.recv(1024))
for z in clientList:
z.send(str.encode(y + " connected"))
while True:
try:
v = bytes.decode(x.recv(1024))
q = str(y)
h = q + " sent: " + v
print(h)
for z in clientList:
z.send(str.encode(h))
if v == "disconnect":
x.send(str.encode("disconnect"))
clientList.remove(x)
x.close()
threading.current_thread()._delete()
break
time.sleep(0.01)
except:
clientList.remove(x)
for z in clientList:
z.send(str.encode(y + " disconnected"))
print(y + " disconnected")
x.close()
threading.current_thread()._delete()
break
func()
This is the Client:
import socket
import threading
import time
HOSTNAME = "192.168.56.1" # server local ip
PORT = 8080
def Listen(i):
while True:
try:
k = bytes.decode(i.recv(1024))
if k == "disconnect":
i.close()
threading.current_thread()._delete()
break
print(k)
time.sleep(0.01)
except:
print("Disconnected")
i.close()
threading.current_thread()._delete()
break
def Activate(i):
t = threading.Thread(target=Listen, args=(i,))
t.start()
def InputHandler():
while True:
time.sleep(1)
v = input("")
if v == "connect":
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOSTNAME, PORT))
s.send(str.encode("connected"))
Activate(s)
time.sleep(1)
except:
print("Failed")
elif v == "close":
try:
s.send(str.encode("disconnect"))
break
except:
break
else:
try:
s.send(str.encode(v))
except:
print("Failed")
InputHandler()
any ideas what's wrong? please let me knwow.
According to my knowledge, you shouldn't need port forwarding for the simple case you are describing
(that is: if both machines are on the same LAN).
But the link provided by #AvivYaniv in the comments though has some notes about what you are asking which are:
If you're trying to connect from inside the same LAN, there's a very easy solution: use the server's real internal address, not the router's external address.
It seems like you already know what is the IP address of the server machine,
because in the client you write the HOSTNAME variable as equal to 192.168.56.1.
Anyway though try setting your server's bind address to empty. ie instead of:
HOSTNAME = socket.gethostbyname(socket.gethostname())
try:
HOSTNAME = ''
at the server side.
Also there are some useful notes on this tutorial like:
A couple things to notice: we used socket.gethostname() so that the socket would be visible to the outside world. If we had used s.bind(('localhost', 80)) or s.bind(('127.0.0.1', 80)) we would still have a "server" socket, but one that was only visible within the same machine. s.bind(('', 80)) specifies that the socket is reachable by any address the machine happens to have.
Edit 1:
If you are not using VMs, then no problem: just find the IP of the server machine and put into the HOSTNAME of the client. If you set the server's HOSTNAME to empty then the client should connect to the IP of the server. Try finding your IP (NOT the router's external IP but your server's machine LAN IP). For example if your are on Windows, go to Control Panel like shown in this tutorial.
My client initially communicates using persistent HTTP with my own server. I am now trying to insert a web proxy in between them, so ideally the proxy will maintain 2 seperate persistent connections, one with the client and one with the server. How can I create a python web proxy that does that? I've only been able to create a non-persistent one so far, how would I expand it to do persistent connections?
Code so far:
def main():
# host and port info.
host = '' # blank for localhost
port = 80
try:
# create a socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# associate the socket to host and port
s.bind((host, port))
# listenning
s.listen(BACKLOG)
except socket.error, (value, message):
if s:
s.close()
print "Could not open socket:", message
sys.exit(1)
# get the connection from client
while 1:
print "Proxy running..."
conn, client_addr_port = s.accept()
# create a thread to handle request
thread.start_new_thread(proxy_thread, (conn, client_addr_port))
s.close()
def proxy_thread(conn, client_addr_port):
print "received something...creating new thread"
global threadcount
client_addr = client_addr_port[0]
client_port = client_addr_port[1]
# Check if this is an new video flow (assumption now is that 1 client has 1 video flow, and the video does not terminate)
if client_addr not in client_vid_flows:
print "New client detected", client_addr
client_vid_flows[client_addr] = 0 # Expand to save video rate
# ctrl_msg_timer(client_addr) # Start timer that sends a ctrl_msg to the switch at a certain frequency
with lock:
threadcount = threadcount + 1
print "Thread number:", threadcount
# get the request from browser
request_text = conn.recv(MAX_DATA_RECV)
request = HTTPRequest(request_text)
if not request:
sys.exit(1)
if request.error_code:
sys.exit(1)
host = request.headers['host']
port_pos = host.find(":") # find the port pos (if any)
if (port_pos==-1): # default port
webserver = host
port = 80
else: # specific port
webserver = host.split(":")[0]
port = host.split(":")[1]
print "Connect to: %s:%i" % (webserver, port)
try:
# create a socket to connect to the web server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((webserver, port))
s.send(request_text) # send request to webserver
while 1:
# receive data from web server
data = s.recv(MAX_DATA_RECV)
print data
if (len(data) > 0):
# send to browser
conn.send(data)
print 'more to send, len(data)={}'.format(len(data))
else:
print 'end of send'
# s.close()
# conn.close()
except socket.error, (value, message):
if s:
s.close()
if conn:
conn.close()
print "Runtime Error:", message
sys.exit(1)
print "--------------------------------"
#********** END PROXY_THREAD ***********
if __name__ == '__main__':
main()
From wireshark, I see that a request packet is being sent to the proxy. However, the proxy is not picking this up.