I'm trying to copy the features of this library https://github.com/rnbguy/pysphere/blob/master/misphere.py which connects via websockets to the Mi Sphere 360 camera.
The important code is here
ms_ip = '192.168.42.1'
ms_tcp_port = 7878
ms_uk_port = 8787
ms_fs_port = 50422
def init(self):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
self.socket.connect((self.ms_ip, self.ms_tcp_port))
self.socket_1 = socket.socket()
self.recv_handle_live = True
self.recv_thread = threading.Thread(target=self.recv_handler)
self.recv_thread.daemon = True
self.session = Session()
self.session.conf = {}
self.session.locks = {}
self.last_send = 0
I'm trying to do this with the ws library in Node
const ip = '192.168.42.1'
const port = '7878'
const url = `ws://${ip}:${port}`
const websocket = new WebSocket(url)
However I'm not getting a connection to the camera. (It's connected via Wifi, but the websocket never sends a connection message)
I'm wondering if it's to do with the protocols, which are listed in the Phython code.
I see in the websocket documentation you can define protocols in the connection, but I can't find any documentation about what those protocols are and how you add them.
i.e.
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
Anyone know how I add something like this in the Node websocket connection?
A webSocket connection cannot be made to a plain TCP socket server.
A plain TCP socket is not the same as a webSocket. Your Python code appears to be making a plain TCP socket connection.
Your node.js code is attempting to make a webSocket connection. A webSocket connection can only be made to a webSocket server that speaks the webSocket protocol (which runs on top of a plain TCP socket).
If your Python code is working, then you apparently need to make just a plain TCP socket connection which you can see how to do in the Net module.
For further description of the differences between a plain TCP connection and a webSocket connection see these:
Computer refuses websocket connections
What's the difference between WebSocket and plain socket communication?
Is there a way to do a tcp connection to an IP with javascript?
Socket server not connect with JavaScript socket client
To connect to a regular TCP socket, use net package instead of a WebSocket. Example Node equivalent code:
const net = require('net');
const port = 7878
const ip = "192.168.42.1"
const socket = net.createConnection(port, ip);
socket.on('connect', () => {
console.log("socket connected");
});
Related
I'm trying to send data to a python server:
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(('127.0.0.1',6000))
s.listen(5)
while True:
clientsocket,address = s.accept()
print(f"Got connection from {address} !")
from godot:
var socket = PacketPeerUDP.new()
socket.set_dest_address("127.0.0.1",6000)
socket.put_packet("quit".to_ascii())
based on this link
but it doesn't seem to be working, How do I send the data?
i'm not that familiar with python servers, but it looks like you have a python server that listens for TCP connections but in godot you connect via UDP Client.
As seen in this Answer SOCK_STREAM is for TCP Server and SOCK_DGRAM for UDP.
I am not sure which of those you want to use. An example server for UDP would be:
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind(('127.0.0.1',6000))
bufferSize = 1024
#s.listen(5)
print("running")
while True:
bytesAddressPair = s.recvfrom(bufferSize)
message = bytesAddressPair[0]
clientMsg = "Message from Client:{}".format(message)
print(clientMsg)
I copied most of it from here : Sample UDP Server
If you wanted to have a TCP Server you should alter the Godot part to use a TCP Client. See the official docs here
figured it out thanks to #René Kling 's answer
just incase someone wants the complete version
python server:
import socket
HOST = "127.0.0.1"
PORT = 6000
s= socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.bind((HOST, PORT))
while True:
message, addr = s.recvfrom(1024)
print(f"Connected by {addr}")
Godot:
extends Node2D
tool
export(bool) var btn =false setget set_btn
var socket = PacketPeerUDP.new()
func set_btn(new_val):
socket.set_dest_address("127.0.0.1", 6000)
socket.put_packet("Time to stop".to_ascii())
First of all I am not talking about a tcp or udp or socket implemented in a vps or server
My question is just like client to client socket communication.
Imagine listening at your home pc with a tcp socket. You can connect to this from home inter network anyway. But suppose someone wants to connect to it via the internet. Then you can create a forwarding rule on the router and bring it to working condition. Then the router knows that if an incoming connection comes from a port, the connection will be forwarded to the device in the relevant inter network.
But the ISP I use does not support port forwarding.
I thought these were not impossible because of the team-viewer software. Because when I was connected to a friend in team-viewer, I opened the wire-shark and reviewed it.
Then I saw that the data packet is exchanged peer to peer. Because the destination source addresses were my ip and friend's ip
This means that the video data is exchanged without the participation of an additional server
I highlighted the team-viewer connection.
61.245.175.81 is my friend's public IP. 192.168.1.130 is my internal IP
I want to do the same
Here is my simple socket code. This does not work through the internet because there is no router forwarding rule. I am very new to socket and networking side
Sever
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(('', 12000))
while True:
message, address = server_socket.recvfrom(1024)
message = repr(message)
print("Connected from -> " + str(address) )
print("Received data -> " + message)
reply = b"Hi from server :) "
server_socket.sendto(reply, address)
Client
import time , datetime
import socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client_socket.settimeout(1.0)
message = bytes(str(datetime.datetime.now()),'utf-8')
addr = ("192.168.1.130", 12000)
client_socket.sendto(message, addr)
try:
data, server = client_socket.recvfrom(1024)
print( repr(data) )
except: #socket.timeout:
print('REQUEST TIMED OUT')
Can anyone give an explanation for my question
Pretty sure they do it using UDP hole punching, you'd need to do something similar to implement this.
In a nutshell two clients behind NAT (which is what your router is doing) can use a third server acting as a sort of mediator to establish a connection.
I'm trying to run the below program but I keep getting connection error's:
from socket import *
from codecs import decode
HOST = 'localhost'
PORT = 5000
BUFSIZE = 1024
ADDRESS = (HOST, PORT)
server = socket(AF_INET, SOCK_STREAM)
server.connect(ADDRESS)
dayAndTime = decode(server.recv(BUFSIZE), 'ascii')
print(dayAndTime)
server.close()
ERROR: ConnectionRefusedError: [Errno 61] Connection refused
Any idea what's going on?
If your book doesn't mention the other half of sockets, you need a better book.
Socket basics are easy. You have one process listen on a port, waiting for connections. Commonly we'll call this a 'server'. Another process (perhaps on the same machine, perhaps remote) attempts to connect to that port. We'll call that the client.
If no one is listening, then when the client attempts to connect they'll get your error Connection Refused.
So, set up a listening process. Below, on the left is server code; on the right is client code. Top-to-bottom is the "flow".
server = socket(AF_INET, SOCK_STREAM) # <- just like your example
server.bind(ADDRESS) # rather than 'connect', we 'bind' to the port
server.listen(1) # bind "claims" the port, so next we call listen & wait...
# Meanwhile...
# Your client process
client = socket(AF_INET, SOCK_STREAM)
client.connect(ADDRESS)
# It's only at this moment that the client reaches across the network to the server...
# On connect, the listening server wakes up, and needs to "accept" the connection
(s, remote_addr) = server.accept()
Once accepted, you can now send/recv on the s socket on the server-side, and send/recv from the client socket on the client side. Note that the server variable is not the socket to communicate on -- it's used to listen for new connections. Instead, you read/write on the socket object returned as first item of accept().
There's lots more to consider but this is at the heart of the Internet and has been pretty much unchanged since the 1980s.
Image from wikipedia entry for Berkeley Sockets:
Having great difficulty getting a response, even a reassuring error response, after attempts to connect to Coinfloor's websocket API. Docs here: https://github.com/coinfloor/API/blob/master/WEBSOCKET-README.md
'Commands, replies, and notifications traverse the WebSocket in text
frames with JSON-formatted payloads.'
Here is my attempt:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server = 'api.coinfloor.co.uk'
port = 443
server_ip = socket.gethostbyname('api.coinfloor.co.uk')
payload = '{"method": "WatchTicker","base": int("0xF800", 16),"counter":int("0xFA20",16),"watch":True}'
s.connect((server_ip, port))
s.sendall(payload.encode('utf-8'))
result = s.recv(4096)
print(result)
It just returns this:
b''
i.e. an empty byte string.
Because sockets and WebSocket are completely different things. AF_INET/SOCK_STREAM socket is a facility that uses TCP to communicate to the remote peer. On the other hand, WebSocket is a binary protocol that
Works on the top of TCP or TLS.
Has to perform HTTP handshake before data exchange.
Since WebSocket is a rather complex protocol (see the standard), your best course of action is to find a WebSocket library and use it instead of trying to implement the protocol starting from TCP.
I have set up a server socket (plain raw socket) listening on port A. A client now connects to this server. OS opens up a port for the client for this purpose. Say port B is allocated to this client. Now my question is, can a 3rd script connect to this port B and send data. Or in other words can I spoof a response to the client as if it was coming from the server? I tried spoofing it using scapy, but it wasnt working.
server.py
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("localhost", A))
s.listen(10)
ns, cli_addr = s.accept()
time.sleep(30) # so that i can trigger my 3rd script
goodclient.py
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("localhost", A))
print s.getsockname() # to get the local port of client - B
s.recv(1024)
badboy.py
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("localhost", B)) # connection refused error
s.send("hihihi")
scapybadboy.py
pack = IP(src="localhost", dst="localhost") / TCP(sport=A, dport=B) / "Hello"
send(pack) # Packet sent but not received by the client
Because server and client using SOCK_STREAM sockets, they both aware of TCP session(including port, IP and (SEQ_NUMBER,ACK_NUMBER)), so when session is already in process, you will have to perform TCP hikacking and IP spoofing in order to send messages in stream.
In other words, you will have to guess(or steal) ACK number of server in order to send fake messages to client using badclient.
However, if you will make somehow goodclient answer you and not a server you should run the following:
iptables -A FORWARD -j NFQUEUE --queue-num 1 , because your operating system doesn't know about session that you just "opened" with goodclient and it will send RST packet. This command will prevent it.