First off, thanks to all users because I learnt a lot reading questions and answers on this website.
I'm starting to learn Python and I'm trying to send information of a PC over internet through sockets to another PC. It all worked great when I connected two computers of my localhost. However, I'm trying to connect with a friend's computer and I can't do it. I know (thanks to previous topics on this page) that the server needs to forward a port to his own computer. My friend already did that and, me as a client and he as a server, we haven't been able to connect.
I'd like to show you my really simple code because I'm sure I mistaken something I can't figure out what.
This is the client script:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("Public IP of server",9990))
if True:
print "Conexion establecida"
while True:
mensaje = raw_input("Mensaje a enviar: ")
if mensaje == "close":
break
else:
s.send(mensaje)
print "Mensaje enviado."
s.close()
And this is the server script:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("",9990))
s.listen(1)
sc, addr = s.accept()
print "Conexion establecida con ", str(addr[0])
while True:
recibido = sc.recv(1024)
if recibido == "close":
break
print str(addr[0]) + " dice: ", recibido
sc.close()
s.close()
The client script connect with the public ip the server and, if true, let the user send a message. The server scripts just receives the message and prints it. I hope it is enough to no not make you lose a lot of time. Lot of thanks for reading me!
Related
A little summary, i programm a socket server in python to fetch data from my MSSQL database and send it to my Flutter App. So far so good. Now i tried to test it from outside. I set a Port Forwarding and tried to connect it. btw it works fine. I let the server run for few hours and now i get a error messenge.
See the pic, the first ip is mine but the second is not.
Someone is trying to connect to my server. How do solve this Problem
MY Python Code
from datetime import datetime
import socket
from SqlServerRequest import SqlServerRequest
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('192.168.43.126', 2222))
s.listen(5)
while True:
clientsocket, address = s.accept()
print(f"Connection from {address} has been established.")
data = clientsocket.recv(2048).decode()
print(data)
if data == "open":
o = SqlServerRequest.dataForOpenOrders()
clientsocket.sendall(bytes(o,"utf-8"))
if data == "closed":
c = SqlServerRequest.dataForClosedOrders()
clientsocket.sendall(bytes(c,"utf-8"))
clientsocket.close()
Well, you did set up port forwarding to allow anyone on the internet to connect to your machine. Someone just did, and sent something to your program that it didn't expect, and your program crashed.
That's a great lesson on making your program robust in the face of unexpected input, for instance.
Secondly, if you want your program to actually be accessible on the internet, you will probably want some sort of authentication -- for instance, a password known by your Flutter client.
Likely on top of that, you'd want some sort of transport-layer security so people can't read your data in-flight.
The crash happens because you're trying to convert to Unicode. If this is really all there is, then it's silly to convert to Unicode at all. Just leave it as a bytes string.
wwhile True:
clientsocket, address = s.accept()
print(f"Connection from {address} has been established.")
data = clientsocket.recv(2048)
print(data)
if data == b"open":
o = SqlServerRequest.dataForOpenOrders()
clientsocket.sendall(bytes(o,"utf-8"))
if data == b"closed":
c = SqlServerRequest.dataForClosedOrders()
clientsocket.sendall(bytes(c,"utf-8"))
clientsocket.close()
In trying to familiarize myself with the socket library, I have a simple server and client setup. Basically I've stumbled through and am able to set up connection and get the server and client to talk to each other. To make it more interactive, I have client.py able to send text through the command line. Everything appears to be working properly (with the exception of the server side tearing down connection properly if client input is blank), if I type a message from the client side, it spits it right back out to me. In this example, I have it set up for the server side to print the text as well. What I noticed was, that the server side doesn't alway 'register' what it being sent from the client. I am trying to figure out why this is the case. For being a test, it doesn't really affect anything, I just can't figure out what is taking place behind the scenes.
EDIT:
Actually, after playing around with it for a bit, it appears every other message is being printed out to the server console. I've still yet to figure out why this is the case
Server side:
#server.py
import socket
ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ss.bind(('127.0.0.1',5000))
ss.listen(5)
while True:
conn, addr = ss.accept()
with conn:
print ('Connected by', addr)
while True:
data = conn.recv(4096)
print (data)
if not data:
print ("nothing received from client")
ss.close()
break
Client side:
#client.py
import socket
server = 'localhost'
port = 5000
s = socket. socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 5000))
s.send(bytes(b'Client has connected'))
while True:
msg = input()
s.send(bytes(input(msg),'utf-8'))
if not msg:
print ("Server should tear down connection...")
# s.close()
break
In sockets you there are no methods __exit__ implemented, so you can't use the with conn:
you need to remove this part of code.
I am currently developing a system where I need to send notification to Raspberry to run a Python file. It is much like a observer pattern design where my server is publisher and Raspberry is the observer. Worth to note that, I actually need to interact with one Raspberry at the time (even I have dozens of them). Specifically, on a specific event, I need to warn a single Raspberry that it has to take an action.
I searched for it literally for all the night but I could not find anything coming handy. Nothing really give me a clue how to implement this.
The most close answer I could find is this technology firm's product called PubNub which can actually work. However, as I need is a one-to-one interaction, this might be unnecessary because it is designed to publish a data to multiple clients.
Long story short, I need to trigger Raspberry to take some action in accordance to the some data coming from the server, whenever it receives the data.
Server is running on Amazon and implemented with Python 2.7.
Please do not hesitate to ask me for further detail, if I am missing any.
Thanks for all the supports,
EDIT
Just a recent update with an improvement to my answer. As far as I understand, sockets are able to manage this process. Such as from client (Raspberry in my case) listening for the server and server sending some data. Taken from this site, I managed to make a sample run on my computer, from my local. I used Port 5000 as their 'meeting point'.
Below is the code:
client.py
#!/usr/bin/env python
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 5000
BUFFER_SIZE = 1024
MESSAGE = b"Hello, World!"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(MESSAGE)
data = s.recv(BUFFER_SIZE)
s.close()
print("received data:", data)
server.py
#!/usr/bin/env python
import socket
TCP_IP = '127.0.0.1'
TCP_PORT = 5000
BUFFER_SIZE = 20 # Normally 1024, but we want fast response
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
conn, addr = s.accept()
print('Connection address:', addr)
while 1:
data = conn.recv(BUFFER_SIZE)
if not data: break
print("received data:", data)
conn.send(data) # echo
conn.close()
However, I still have some questions.
Firstly, I want to learn whether the same thing work when I deploy the project and how. If that will work - lets say I have an url for the server like 'www.thisisanexampleurl.com' - simply assignign a port for it, will work?
Secondly, assuming first question is done, what is the way of making it continous so that it does not stop after receiving and sending data once. Because currently, when it makes the data transfer, it stops working.
Thanks again for the all support and again please do not hesitate to ask me for the further details i am missing any.
You should be able to do something this simple:
Run something like this on your pi:
import socket
s = socket.socket()
host = ""
port = 12345
s.bind((host, port))
s.listen(5)
while True:
try:
clientsock, addr = s.accept()
except OSError:
continue
message = clientsock.recv(20)
#the code you want to run
print("doing %s" % message)
clientsock.close()
And this on your server every time you want the pi to take action:
import socket
s = socket.socket()
host = "0.0.0.0"
port = 12345
s.connect((host, port))
s.send("foo")
s.close()
Have a look at Pyro4. It lets you avoid having to write network code at all and just write code that calls remote Python objects as if they were running on the same machine. In your case, the server could call a normal Python method on your Raspberry Pi to do something. It has many features but you can start with something extremely simple.
raspberry pi code:
import Pyro4
#Pyro4.expose
class Raspberry:
def something(self, arg):
print("called with:", arg)
return "hi from pi"
Pyro4.Daemon.serveSimple({Raspberry: "raspberry"})
server code to make the pi do something:
import Pyro4
rasp = Pyro4.Proxy("PYRONAME:raspberry")
print(rasp.something(42))
I am trying to learn Socket coding right now, and I wrote a little piece of Process-to-Process communication.
This is the Servercode:
import socket
s = socket.socket()
host = socket.gethostname()
port = 17752
s.bind((host, port))
s.listen(5)
while True:
(client, address) = s.accept()
print(address, 'just connected!')
message = input("Would you like to close the connection? (y/n)")
if message == 'y':
message = "False"
client.send(message.encode(encoding="utf_8"))
client.close()
break
elif message == 'n':
print("sending message...")
testing = "Do you want to close the connection?"
client.send(testing.encode(encoding='utf_8'))
print("sent!")
And the Clientcode:
import socket
client = socket.socket()
host = socket.gethostname()
port = 17752
client.connect((host, port))
while True:
print("awaiting closing message...")
closing = client.recv(1024)
closing = closing.decode(encoding='utf_8')
print("Closing message recieved and decoded")
if closing == 'False':
print("message is false, breaking loop")
break
else:
print("Awaiting message...")
recieved = client.recv(1024)
recieved = recieved.decode(encoding='utf_8')
print("Message recieved and decoded")
print(recieved)
sd = input('(y/n) >')
if sd == 'y':
print("Closing connection")
client.close()
break
print("Sorry, the server closed the connection!")
What it is meant to do?
It is basically to learn and practice socket coding.
It should be a program that sends data from the Server to the Client with both being able to terminate the connection by answering y or n to the questions.
If both sides keep answering n the program just keeps running.
As soon as someone answers y it terminates either the Server or the client.
Now, I don't know what to heck is wrong there.
If I type 'y' for the Servers question "Would you like to close this connection?" it all works as it should.
If I type 'n' the Server does what it should, but the client does not recieve anything. Most of the 'print' statements are for debugging. Thats how I know the Server works fine.
What is wrong there? I tried to find it, I couldn't.
I am kinda new to python and new to socket coding. So keep it easy please.
Thanks.
(I run it with Batch scripts under Win10 cmd)
(Since it is Process-to-Process it is probably not called a "Server"?)
In you code each connect should have a matching accept on server side.
Your client connects once per session,
but the server accepts after each message, so at the point where the second recv is invoked the server is already trying to accept another client.
Apparently your server is supposed to handle only one client,
so you can just move the call to accept out of the loop:
s.listen(5)
(client, address) = s.accept()
print(address, 'just connected!')
while True:
message = raw_input("Would you like to close the connection? (y/n)")
I'm currently working on with Sockets using Python.
As a starter, I tried copying first the examples given in this (17.2.2. Example) tutorial
I put the client and the server scripts in two different machines (of course)
Now, I want to try if it works, but I'm kind of lost.
I'm thinking of running the server program continuously so that it will keep on receiving the data sent by the client program. However, when I tried to run the Server program, it is giving me this error
socket.error: (99, 'Cannot assign requested address')
and When I tried running the client program, it doesnt give me errors, however, it is printing random data, which is different from what I'm expecting because I sent the String "Hello World", So im expecting that it will receive and print "Hello World"
Shown below is the server program
# Echo server program
import socket
HOST = '192.168.104.112' # Symbolic name meaning all available interfaces
PORT = 50007 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
data = conn.recv(1024)
if not data: break
conn.sendall(data)
conn.close()
and the one below is the client program
# Echo client program
import socket
HOST = '192.168.104.111' # The remote host
PORT = 50007 # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall('Hello, world')
data = s.recv(1024)
s.close()
print 'Received', repr(data)
Assuming that the IP of the machine that runs the server program is : 192.168.104.111
while the Client program is : 192.168.104.112
Im not really sure where to get the port number so I just used the port showed in the rpyc in the terminal. how do I get the correct port number anyway?
I know I made a lot of mistakes here. I just don't which part. Could you point me the mistakes that i've done and how to correct them? and how do I run these programs?
BTW, i'm using Centos.
On the server, HOST should be either 0.0.0.0 or the server's own IP address. The server needs to bind its listening port to its own interface(s). The client connects to the server.
Your client program doesn't check for errors. So if it can't connect to the server, things go awry.