Why is the client not connecting to my tcp server? - windows

I'm unable to connect to my server with the client eventhough. My laptop acts as the client and my PC acts as the server, they are connected to the same wifi. I tried turning the windows firewall off but it didn't help. This is the error code my laptop (client) is getting: Error: Os { code: 10061, kind: ConnectionRefused, message: "No connection could be made because the target machine actively refused it." }
Client code that runs on the laptop:
use std::io::prelude::*;
use std::net::TcpStream;
fn main() -> std::io::Result<()> {
let mut stream = TcpStream::connect("localhost:8080")?;
stream.write(&[1])?;
stream.read(&mut [0; 128])?;
Ok(())
} // the stream is closed here
Server code that runs on the PC:
use std::net::{TcpListener, TcpStream};
use std::io::{Read, Write};
use std::io::{BufReader,BufWriter};
fn handle_client(stream: TcpStream) {
// ...
let mut reader = BufReader::new(&stream);
let mut response = String::new();
reader.read_to_string(&mut response).unwrap();
println!("{}", response);
}
fn main() -> std::io::Result<()> {
let listener = TcpListener::bind("0.0.0.0:8080")?;
// accept connections and process them serially
for stream in listener.incoming() {
handle_client(stream?);
}
Ok(())
}

You need to specify hostname or IP of the other machine instead of localhost. You can find it by hand and hardcode it. If you want your program to find the other machine on your local network automatically, that's a complex annoying problem which itself is way bigger than what you're trying to do here.
After you connect both machines, you'll find that your programs gets stuck.
That's because read_to_string never stops reading until the connection is entirely closed. TCP is not message-based, so the other side will not read a single write, it will keep reading and waiting until the other side hangs up. You will need to devise a protocol that knows exactly how many bytes it needs to read, before reading them, and won't ask for a byte more (e.g. send length of a string before the string).

Related

When making a go RPC call , the return type is channel

Firstly, here is a PRC server. Please notice one of the return type is chan:
func (c *Coordinator) FetchTask() (*chan string, error) {
// ...
return &reply, nil
}
Then the client makes a RPC call. Typically the caller will get a channel which type is *chan string.
call("Coordinator.FecthTask", &args, &reply)
Here is my question. If the server continuously write into the channel:
for i := 0; i < 100; i++ {
reply<- strconv.Itoa(i)
}
🎈🎈🎈 Can the client continuously read read from the channel?
for {
var s string = <-reply
}
I guess the client can't, cuz server and client are not in the same memory. They communicate via Internet. Therefore, even the variable reply is a pointer, it points different address in server and client.
I'am not sure about it. What do you think of it? Thanks a lot!!!!
🎈🎈 BTW, is there anyway to implement a REAL, stateful channel between server and client?
As you already mentioned, channels are in memory variables and it is not possible to use them in other apps or systems. In the other hand gRPC will pass and parse binary data which in this case again passing a channel pointer, will only returns the pointer address in server's memory. After client receiving that address it will try to point to that address in local machine's memory which will can be any sort of data unfortunately.
If you want to push a group of data (let's say an array of strings) you can use a Server streaming or Bidirectional streaming.
In the other hand if you want to accomplish some sort of stable and keep-alive connection you can consider websockets too.

How to spin up a rocket server along with other stuff?

Basically I want to have a single process handling multiple things at the same time (specifically want to have an http endpoint for monitoring a non-http service), but it seems I'm being caught up in Rocket depending on a rocket-specific tokio runtime and I'm not seeing how to get around this. I've thought about having rocket be the main entry point instead of tokio's standard one and launching other stuff from that runtime, but this seems wrong in general and fragile as I might switch libraries. I've thought about using hyper and warp and I'm somewhat confident I could make them work in this situation but want to use rocket as I'm using it elsewhere in this project. I'm using the 0.5-rc01 version.
From the docs:
Rocket v0.5 uses the tokio runtime. The runtime is started for you if you use #[launch] or #[rocket::main], but you can still launch() a Rocket instance on a custom-built runtime by not using either attribute.
Unfortunately I cannot find any further explanation of what requirements this custom-built runtime has nor any examples not using the launch/main macros.
Here's a simplified version of the code I'm trying to use:
#[rocket::get("/ex")]
async fn test() -> &'static str {
"OK"
}
#[tokio::main]
async fn main() {
tokio::spawn(async {
let config = Config {
port: 8001,
address: std::net::Ipv4Addr::new(127, 0, 0, 1).into(),
..Config::debug_default()
};
rocket::custom(&config)
.mount("/", rocket::routes![test])
.launch()
.await;
});
let start = Instant::now();
let mut interval = interval_at(start, tokio::time::Duration::from_secs(5));
loop {
interval.tick().await;
println!("Other scheduled work");
}
}
When I press CTRL-C to terminate the process, the following is printed:
^CWarning: Received SIGINT. Requesting shutdown.
Received shutdown request. Waiting for pending I/O...
Warning: Server failed to shutdown cooperatively.
>> Server is executing inside of a custom runtime.
>> Rocket's runtime is `#[rocket::main]` or `#[launch]`.
>> Refusing to terminate runaway custom runtime.
Other scheduled work
Other scheduled work
Other scheduled work
I've found this documentation explaining that you need to 'cooperate' in shutdown if you're using a custom runtime but it does not explain what cooperation entails. Also, running things besides rocket in the spawned thread causes CTRL-C to kill the process as I would have normally expected, so I think this is related to rocket specifically. What do I need to do so that I can actually kill the process?
Edit: I gave up and switched to warp, which was a thousand times easier. I would still be curious to know the proper way to do this with rocket and would try again if anybody has suggestions.
If we add a config for shutdown to the Rocket.toml, the thread also terminates.
[default.shutdown]
ctrlc = false
signals = ["term", "hup"]
See the documentation for Rocket Shutdown here:
https://api.rocket.rs/v0.5-rc/rocket/config/struct.Shutdown.html#example
I think you could just let Rocket take care of starting your tokio runtime:
#[rocket::main]
async fn main() {
tokio::spawn(async {
let start = Instant::now();
let mut interval = interval_at(start, tokio::time::Duration::from_secs(5));
loop {
interval.tick().await;
println!("Other scheduled work");
}
});
let config = Config {
port: 8001,
address: std::net::Ipv4Addr::new(127, 0, 0, 1).into(),
..Config::debug_default()
};
rocket::custom(&config)
.mount("/", rocket::routes![test])
.launch()
.await;
}
Your own extra logic can be done in the task you spawn and rocket gets launched the normal way.

Wrong response to AT command via socket c++/cli

I want to create simple socket that will communicate with another device via AT commands.
I'm using C++/CLI on Visual 2017.
This is my code
#include "stdafx.h"
#include <conio.h>
using namespace System;
using namespace System::Net;
using namespace System::Net::Sockets;
using namespace System::IO;
int main(array<System::String ^> ^args)
{
int bufferSize = 1024;
array<Byte>^ sendBuffer = gcnew array<Byte>(bufferSize);
array<Byte>^ recvBuffer = gcnew array<Byte>(bufferSize);
try {
// Establish the remote endpoint for the socket.
IPHostEntry^ ipHostInfo = Dns::Resolve("192.168.1.1");
IPAddress^ ipAddress = ipHostInfo->AddressList[0];
IPEndPoint^ remoteEP = gcnew IPEndPoint(ipAddress, 1234);
// Create a TCP/IP socket.
Socket^ socket = gcnew Socket(AddressFamily::InterNetwork,SocketType::Stream, ProtocolType::Tcp);
// Connect the socket to the remote endpoint. Catch any errors.
try {
socket->Connect(remoteEP);
// Encode the data string into a byte array.
array<Byte>^ msg = Text::Encoding::ASCII->GetBytes("AT");
// Send the data through the socket.
int bytesSent = socket->Send(msg);
// Receive the response from the remote device.
int bytesRec = socket->Receive(recvBuffer);
Console::WriteLine("Echoed test = {0}", Text::Encoding::ASCII->GetString(recvBuffer, 0, bytesRec));
// Release the socket.
socket->Shutdown(SocketShutdown::Both);
socket->Close();
}
catch (ArgumentNullException^ ane) {
Console::WriteLine("ArgumentNullException : {0}", ane->ToString());
}
catch (SocketException^ se) {
Console::WriteLine("SocketException : {0}", se->ToString());
}
catch (Exception^ e) {
Console::WriteLine("Unexpected exception : {0}", e->ToString());
}
}
catch (Exception^ e) {
Console::WriteLine(e->ToString());
}
_getch();
return 0;
}
For command there, the response is:
Echoed test = ????????
In ASCII there are weird values: 255,251,3,255,251,1,255,254,1,255,253
The answer should be OK or ERROR
I tested it via Telnet on 192.168.1.1 1234 and it was working fine.
Standard warning: While it's certainly possible to write the main body of your application in C++/CLI, it is not recommended. C++/CLI is intended for interop scenarios: where C# or other .Net code needs to interface with unmanaged C++, C++/CLI can provide the translation between the two. For primary development, it is recommended to use C# if you want managed code, or C++ if you want unmanaged.
That said...
The telnet protocol is not, contrary to popular belief, a raw TCP socket. There is a protocol for communicating options between telnet clients.
What you're seeing there are telnet commands sent from the server. These would be received from by your telnet client, and used to modify how it behaves. This is why everything works when you use a real telnet client: It takes those bytes and interprets the commands properly.
I read the Telnet spec for a few minutes, here's what I was able to decode from the data you posted:
255: IAC, "Interpret as command". This is the escape character for all Telnet commands.
251: WILL: Indicates that the server wants to/is performing an option.
3: SUPPRESS-GO-AHEAD: Apparently Telnet is a half-duplex protocol by default, and the "Go Ahead" is the marker for one side to tell the other, "OK, your turn". This option turns it into a full-duplex connection.
255: IAC
251: WILL
1: ECHO: Indicates that the server will echo back the characters that it receives.
255: IAC
254: DON'T: Indicates that the server is requesting that the client not do something.
1: ECHO: Indicates that the server wants the client to not echo back received characters.
255: IAC
253: DO: Indicates that the server wants the client to turn on some option.
OK, so now that we know what's going on, how do we fix this? I see a few options:
You said you wanted to use "AT Commands" to talk to a device. AT commands are what you use to talk to modems. I'm assuming that you have some serial device, possibly a modem, that you have connected to a little converter device that exposes a serial port as a TCP connection. If so, then there may be some option for that converter device to disable the Telnet protocol, and expose it as "raw", or something similar. If this is true, then that's probably the best option.
You can add code to your program to look for the IAC byte, and handle the bytes that follow it. If it's just a few commands at the beginning of the connection, then you can just expect those fixed bytes; if the commands are sent during the connection, you'll need to handle them everywhere. It's up to you how much you want to handle them. (E.g., if the server says DON'T SUPPRESS-GO-AHEAD, will you send the Go ahead command? Ideally you would, but if your particular connection never says that, then perhaps not.)
There may be a telnet library that will handle the protocol stuff for you. I have not searched for this.
Telnet references:
The main RFC, where the IAC byte and the command bytes are defined: https://www.rfc-editor.org/rfc/rfc854
The ECHO option: https://www.rfc-editor.org/rfc/rfc857
The SUPPRESS-GO-AHEAD option: https://www.rfc-editor.org/rfc/rfc858
Not an official reference, but does list the options that can be specified with WILL, WON'T, DO, and DON'T, and the RFCs they're defined in: http://mars.netanya.ac.il/~unesco/cdrom/booklet/HTML/NETWORKING/node300.html

concurrent relaying of data between multiple clients

I am currently working on an application relaying data sent from a mobile phone via a server to a browser using WebSockets. I am writing the server in go and I have a one-to-one relation between the mobile phones and the browsers as shown by the following illustration.
.
However, I want multiple sessions to work simultaneously.
I have read that go provides concurrency models that follow the principle "share memory by communicating" using goroutines and channels. I would prefer using the mentioned principle rather than locks using the sync.Mutex primitive.
Nevertheless, I have not been able to map this information to my issue and wanted to ask you if you could suggest a solution.
I had a similar to your problem, I needed multiple connections which each send data to each other through multiple servers.
I went with the WAMP protocol
WAMP is an open standard WebSocket subprotocol that provides two application messaging patterns in one unified protocol:
Remote Procedure Calls + Publish & Subscribe.
You can also take a look at a project of mine which is written in go and uses the protocol at hand: github.com/neutrinoapp/neutrino
There's nothing wrong with using a mutex in Go. Here's a solution using a mutex.
Declare a map of endpoints. I assume that a string key is sufficient to identify an endpoint:
type endpoint struct {
c *websocket.Conn
sync.Mutex // protects write to c
}
var (
endpoints = map[string]*endpoint
endpointsMu sync.Mutex // protects endpoints
)
func addEndpoint(key string, c *websocket.Connection) {
endpointsMu.Lock()
endpoints[key] = &endpoint{c:c}
endpointsMu.Unlock()
}
func removeEndpoint(key string) {
endpointsMu.Lock()
delete(endpoints, key)
endpointsMu.Unlock()
}
func sendToEndpoint(key string, message []byte) error {
endpointsMu.Lock()
e := endpoints[key]
endpointsMu.Unlock()
if e === nil {
return errors.New("no endpoint")
}
e.Lock()
defer e.Unlock()
return e.c.WriteMessage(websocket.TextMessage, message)
}
Add the connection to the map with addEndpoint when the client connects. Remove the connection from the map with removeEndpoint when closing the connection. Send messages to a named endpoint with sendToEndpoint.
The Gorilla chat example can be adapted to solve this problem. Change the hub map to connections map[string]*connection, update channels to send a type with connection and key and change the broadcast loop to send to a single connection.

Boost::asio UDP Broadcast with ephemeral port

I'm having trouble with udp broadcast transactions under boost::asio, related to the following code snippet. Since I'm trying to broadcast in this instance, so deviceIP = "255.255.255.255". devicePort is a specified management port for my device. I want to use an ephemeral local port, so I would prefer if at all possible not to have to socket.bind() after the connection, and the code supports this for unicast by setting localPort = 0.
boost::asio::ip::address_v4 targetIP = boost::asio::ip::address_v4::from_string(deviceIP);
m_targetEndPoint = boost::asio::ip::udp::endpoint(targetIP, devicePort);
m_ioServicePtr = boost::shared_ptr<boost::asio::io_service>(new boost::asio::io_service);
m_socketPtr = boost::shared_ptr<boost::asio::ip::udp::socket>(new boost::asio::ip::udp::socket(*m_ioServicePtr));
m_socketPtr->open(m_targetEndPoint.protocol());
m_socketPtr->set_option(boost::asio::socket_base::broadcast(true));
// If no local port is specified, default parameter is 0
// If local port is specified, bind to that port.
if(localPort != 0)
{
boost::asio::ip::udp::endpoint localEndpoint(boost::asio::ip::address_v4::any(), localPort);
m_socketPtr->bind(localEndpoint);
}
if(m_forceConnect)
m_socketPtr->connect(m_targetEndPoint);
this->AsyncReceive(); // Register Asynch Recieve callback and buffer
m_socketThread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&MyNetworkBase::RunSocketThread, this))); // Start thread running io_service process
No matter what I do in terms of the following settings, the transmit is working fine, and I can use Wireshark to see the response packets coming back from the device as expected. These response packets are also broadcasts, as the device may be on a different subnet to the pc searching for it.
The issues are extremely strange to my mind, but are as follows:
If I specify the local port and set m_forceConnect=false, everything works fine, and my recieve callback fires appropriately.
If I set m_forceConnect = true in the constructor, but pass in a local port of 0, the transmit works fine, but my receive callback never fires. I would assume this is because the 'target' (m_targetEndpoint) is 255.255.255.255, and since the device has a real IP, the response packet gets filtered out.
(what I actually want) If m_forceConnect = false (and data is transmitted using a send_to call), and local port = 0, therefore taking an ephemeral port, my RX callback immediately fires with an error code 10022, which I believe is an "Invalid Argument" socket error.
Can anyone suggest why I can't use the connection in this manner (not explicitly bound and not explicitly connected)? I obviously don't want to use socket.connect() in this case, as I want to respond to anything I receive. I also don't want to use a predefined port, as I want the user to be able to construct multiple copies of this object without port conflicts.
As some people may have noticed, the overall aim of this is to use the same network-interface base-class to handle both the unicast and broadcast cases. Obviously for the unicast version, I can perfectly happily m_socket->connect() as I know the device's IP, and I receive the responses since they're from the connected IP address, therefore I set m_forceConnect = true, and it all just works.
As all my transmits use send_to, I have also tried to socket.connect(endpoint(ip::addressv4::any(), devicePort), but I get a 'The requested address is not valid in its context' exception when I try it.
I've tried a pretty serious hack:
boost::asio::ip::udp::endpoint localEndpoint(boost::asio::ip::address_v4::any(), m_socketPtr->local_endpoint().port());
m_socketPtr->bind(localEndpoint);
where I extract the initial ephemeral port number and attempt to bind to it, but funnily enough that throws an Invalid Argument exception when I try and bind.
OK, I found a solution to this issue. Under linux it's not necessary, but under windows I discovered that if you are neither binding nor connecting, you must have transmitted something before you make the call to asynch_recieve_from(), the call to which is included within my this->asynch_receive() method.
My solution, make a dummy transmission of an empty string immediately before making the asynch_receive call under windows, so the modified code becomes:
m_socketPtr->set_option(boost::asio::socket_base::broadcast(true));
// If no local port is specified, default parameter is 0
// If local port is specified, bind to that port.
if(localPort != 0)
{
boost::asio::ip::udp::endpoint localEndpoint(boost::asio::ip::address_v4::any(), localPort);
m_socketPtr->bind(localEndpoint);
}
if(m_forceConnect)
m_socketPtr->connect(m_targetEndPoint);
// A dummy TX is required for the socket to acquire the local port properly under windoze
// Transmitting an empty string works fine for this, but the TX must take place BEFORE the first call to Asynch_receive_from(...)
#ifdef WIN32
m_socketPtr->send_to(boost::asio::buffer("", 0), m_targetEndPoint);
#endif
this->AsyncReceive(); // Register Asynch Recieve callback and buffer
m_socketThread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&MyNetworkBase::RunSocketThread, this)));
It's a bit of a hack in my book, but it is a lot better than implementing all the requirements to defer the call to the asynch recieve until after the first transmission.

Resources