Honestly, I am new in python tcp sockets and I wrote a simple code for the server side.
When I run the code locally, everything is fine and I receive the message from the local server immediately, but when I put the code on a vps (linux) and run the code with python3 test.py and send a message from client to the server, server receive the message from client and waits about 1 minute to send the message back to the client and after that everything is fine and the messages transfer between server and client without any delay. I tested other platforms such as nodejs, other vps and also setting ssl for the vps and using non-blocking mode and changed the recv() buffer size too but I faced the same thing.
I used telnet and a client with python and also faced the same issue.
I will be so thankful if you help me out with this.
Best regards
client (also telnet)
import socket
c = socket.socket()
c.connect(('my_ip',56112))
c.send(bytes("1",'utf-8'))
c.recv(1024).decode()
c.close()
server
import socket
s=socket.socket()
print("socket created!")
s.bind(('0.0.0.0',56112))
s.listen(3)
print("waiting for connections!")
while True:
c, addr = s.accept()
name = c.recv(1024).decode()
print("connected with",addr,name)
c.send(bytes("hi there",'utf-8'))
c.close()
could you help me to solve this?
Related
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
using w10/64, python 3.6, rpyc
I have a server receiving serial data and want the data to be published to any client asking for a connection.
In the server I add every client into a connection list and when detecting changes in the data publish it to all clients.
Clients send a "startListening" request to the server including ip and port. The server then opens its own connection to the client to update it with the new data.
I have an "on_disconnect" method in my servers commands class and it gets triggered when a client stops.
When the client restarts and sends a "startListening" again I get an EOFError on the server showing the clients ip/port.
How can I properly detect and close the client connection to allow for a reconnect?
I have a trial version of a VPS, I want to use this as a server to send commands from a smartphone to the raspberry.
I am using http to send requests to the VPS but how can I redirect the commands received from the smartphone to the raspberry?
You can code a client-side script in Python which reads the response from the VPS each 2 seconds (or other time) and execute the command you want. E.g.
client-side script (read.py)
#client example
import socket, time
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('theVPSip', 80)) # port 80 by default
TIME = 2 # amount of time to wait. Do not saturate VPS server
while 1:
time.sleep(TIME)
data = client_socket.recv(512)
print "RECIEVED:" , data
import subprocess
process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
output = process.communicate()[0]
server-side script
Depending on what language you code, you will use a different syntax (of course). But I'll tell you what you have to do:
Register the Raspberry IP into a variable (only first time, experimenting, then let it fixed)
Register to-be-sent commands in a database
Check if the request comes from the RPi or from the phone.
RPi-> send command to execute as a return in plain text
Phone-> register data (taken from POST/GET request) into database
I suppose you could communicate with the raspberry using other model, but you would need to have a bigger control to the server and be able to run scripts of the kind of a socket connection (e.g. using Python/Java)
I am developing a WebSocket service using NodeJS and Einaros WS module and I have raised this question: NodeJS Einaros WS Connection Timeout which apparently no one know the answer so I presume I should write my own ping pong based system to check whether a client is still connected or not.
I am not sure whether I should write code on server side or client side; I mean if the server should ping the client or... the client (which is my own websocket application) should ping the server.
Is there any difference between both methods ?
It is called a heartbeat and is usually sent by the client every 5 seconds with a ping frame (0x09) as opcode while the server responds with a pong frame (0xA) as opcode.
In theory it doesn't really matter whether it's the server or client initiating the heartbeat, but in a real-world situation it is usually better that the client keep itself updated whether the server is there or not to be able to inform the user as quickly as possible.
I am developing an application that should be able to write to a virtual serial port and receive data through the same port from remote clients over network.
The application runs on a linux server. I am new in using serial ports and I have some questions on this topic.
Clients
The client can establish a TCP connection to a server. When we setup a client, we have to provide the IP address of the server, a tcp port (usually 8080) and a virtual com port.
The client then will automatically try to connect to the server.
Server
The server has a virtual com port, the same we set in the client config (e.g. COM1). When an application on the server writes data to this port, the data should be send to all clients connected via tcp. The response from the clients is send over TCP back to the server which can read it over the virtual serial port.
Question
On windows I used a virtual serial port connector http://www.eterlogic.com/Products.VSPE.html which did most of the work. However I want to solve this problem on linux machines.
My question is, how can I create a TCP server that has a virtual serial port attached and can send/receive data through this port over TCP to listening clients?
Try socat. Possible scenario:
socat pty,link=/dev/virtualcom0,raw tcp:192.168.254.254:8080&
socat creates TCP connection to 192.168.254.254:8080, so that everything, that will be written to /dev/virtualcom0 will be forwarded to 192.168.254.254:8080 and vice versa.
Another approach would be to use RFC2217 via ser2net on Linux sever side and RFC2217 driver on Windows side (for example http://www.hw-group.com/products/hw_vsp/index_en.html single port version). You can also try to get http://pyserial.sourceforge.net/ to work with ser2net.
you have socat and ser2net and other programs but my experience is very bad... not working properly. I've done this small python program, can be useful. Update port, baudrate... then use any tcp client. Remove first line if don't want to use is as auto executable script
#!/usr/bin/python
import socket
import sys
import serial
#open serial port
ser = serial.Serial('/dev/ttyAMA0', 115200, timeout=0)
#create socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
#bond to the port. Don't use localhost to accept external connections
server_address = ('', 2105)
print('starting up on {} port {}'.format(*server_address))
sock.bind(server_address)
#listen
sock.listen(1)
#loop
while True:
#waits for a new connection
print('waiting for a connection')
connection, client_address = sock.accept()
try:
print('connection from', client_address)
#continously send from serial port to tcp and viceversa
connection.settimeout(0.1)
while True:
try:
data = connection.recv(16)
if data == '': break
ser.write(data)
except KeyboardInterrupt:
connection.close()
sys.exit()
except Exception as e:
pass
received_data = ser.read(ser.inWaiting())
connection.sendall(received_data)
except Exception as e:
print e
finally:
#clean up connection
connection.close()
The software will help to establish server and client connection over TCP http://www.serial-com-port.com/
I use it for creating virtual serial communications over network, but I have the real RS232 port on the computer. So I just transfer the data over network. If you need to create a virtual COM on the server too, use the Virtual Serial Port Driver.