C++ boost bad file descriptor - c++

Above is my code which im using calling from my browser and other client. But it doesnt seem to work. Is there anything wrong? I want to know on which ip im running my server and how this can be used to create a restful webservice.
#include <ctime>
#include <iostream>
#include <string>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
using namespace std;
std::string make_daytime_string() {
using namespace std; // For time_t, time and ctime;
time_t now = time(0);
return ctime(&now);
}
int main() {
try {
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 13));
for (;;) {
cout << "listening for socket" << endl;
tcp::socket socket(io_service);
acceptor.accept(socket);
cout << "listening for socket" << endl;
std::string message = make_daytime_string();
boost::system::error_code ignored_error;
boost::asio::write(socket, boost::asio::buffer(message), ignored_error);
}
} catch (std::exception &e) {
std::cerr << e.what() << std::endl;
}
}

I'd guess that you are not running the program with sufficient permission to open the privileged (<1024) port 13.
Trying with 1313 works for me (without administrative privileges)

Related

asio tcp server hanging

I know this is probably a really simple problem but ive been trying to get the asio examples to work correctly for over a week now. whenever I run the program, the terminal hangs and dosent print anything and dosent send any info to the client. Im using Ubuntu Linux and a basic compiler command
g++ main.cpp -o main.exe -I include
#define ASIO_STANDALONE;
#include <ctime>
#include <iostream>
#include <string>
#include <asio.hpp>
using asio::ip::tcp;
int main()
{
try
{
asio::io_context io_context;
tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), 1326));
for (;;)
{
std::cout << "hi";
tcp::socket socket(io_context);
acceptor.accept(socket);
std::string message = "e";
asio::error_code ignored_error;
asio::write(socket, asio::buffer(message), ignored_error);
break;
}
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
any help would be much appreciated
the terminal hangs and dosent print anything and dosent send any info to the client
You need to connect a client first, because the first thing you do is a blocking accept which never completes unless a connection arrives.
I've compiled your program (with minor modification for Boost Asio):
Live On Coliru
//#define ASIO_STANDALONE
#include <boost/asio.hpp>
#include <ctime>
#include <iostream>
#include <string>
namespace asio = boost::asio;
using asio::ip::tcp;
using boost::system::error_code;
int main() {
try {
asio::io_context io_context;
tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), 1326));
for (;;) {
tcp::socket socket(io_context);
acceptor.accept(socket);
std::cout << "hi " << socket.remote_endpoint() << std::endl;
std::string message = "server message works\n";
error_code ignored_error;
asio::write(socket, asio::buffer(message), ignored_error);
break;
}
} catch (std::exception const& e) {
std::cerr << e.what() << std::endl;
}
}
Using netcat to emulate a client:
nc 127.0.0.1 1326 -w 1 <<< "Hello world"
We see:
hi 127.0.0.1:45448
server message works
Or more clearly in separate terminals:

Image shows up corrupted on localhost

I'm horribly new to c++ and programming in general. I'm simply trying to read a picture using opencv and display it on web server using boost asio. This is an initial step before I do this for all frames from a video. The following is my code -
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <thread>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
using boost::asio::ip::tcp;
using namespace std;
using namespace cv;
int main(){
try{
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 1112));
for (;;){
tcp::socket socket(io_service);
acceptor.accept(socket);
boost::system::error_code ignored_error;
cv::Mat frame = cv::imread("x.jpg");
vector<uchar> buff;
vector<int> param = vector<int>(2);
param[0]=cv::IMWRITE_JPEG_QUALITY;
param[1]=95;
imencode(".jpg",frame,buff,param);
const char mess[] = "axaxaxaxasaaaaaaaaaaxax";
std::string content(buff.begin(), buff.end());
boost::asio::write(socket, boost::asio::buffer(content), boost::asio::transfer_all(), ignored_error);
// boost::asio::write(socket, boost::asio::buffer(mess), boost::asio::transfer_all(), ignored_error);
}
}
catch(std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
now sending the message works just fine but when i try to send the image via content or buff, it shows up as gibberish. I feel like it's because I'm not sending any information about the picture prior to sending the picture. But I can't figure out how to do that.
Or maybe I'm entirely wrong. Any help/advice would be appreciated. Cheers!
I've simplified the code a little:
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <opencv2/opencv.hpp>
using boost::asio::ip::tcp;
int main(){
try{
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 1112));
for (;;){
tcp::socket socket(io_service);
acceptor.accept(socket);
cv::Mat frame = cv::imread("x.jpg");
std::vector<uchar> buff;
imencode(".jpg", frame, buff, std::vector<int> { cv::IMWRITE_JPEG_QUALITY, 95 });
boost::system::error_code err;
auto bytes_transferred = boost::asio::write(socket, boost::asio::buffer(buff), boost::asio::transfer_all(), err);
std::cout << "Written: " << bytes_transferred << " (" << err.message() << ")\n";
}
}
catch(std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
(specifically, don't use using namespace unneccessarily, not copying into a std::string unneccessarily, and not ignoring the error code unnecessarily)
Compiled it with
g++ test.cpp -L/usr/local/lib -pedantic -Wall -Wextra -pthread -lope^Cv_{core,imgproc,imgcodecs} -lboost_{system,thread} -o test.exe
Copied a sampe jpeg as x.jpg, running it in a terminal:
./test.exe
Then using netcat to read the result:
netcat localhost 1112 > verify.jpg
The server process will print the same message each time:
Written: 6130 (Success)
(6130 bytes happens to be the 95% re-encoded size of the test image I chose). The resulting image (verify.jpg) looks fine in my image viewer.
Conclusion
I think the code is probably fine (but check with the improvements above) and you might have been testing the result incorrectly.

C++ boost::asio no connection could be made because the target machine actively refused it

This is not a duplicate! (This is not about UDP, it is TCP. This is not C#, Python or whatever, it is C++)
I get the error described in the title if I try to connect through my external IP. However, it works via "localhost" or "127.0.0.1" (I am running client.exe and server.exe on the same machine). This code was copied from an example and I made minor changes.
EDIT: I gave Firewall permission to both executable files. Still, the problem persists.
Server:
#include <ctime>
#include <iostream>
#include <string>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
std::string make_daytime_string()
{
using namespace std; // For time_t, time and ctime;
time_t now = time(0);
return ctime(&now);
}
int main()
{
try
{
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 62000));
for (;;)
{
tcp::socket socket(io_service);
acceptor.accept(socket);
std::string message = make_daytime_string();
boost::system::error_code ignored_error;
boost::asio::write(socket, boost::asio::buffer(message), ignored_error);
}
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
Client:
#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
int main(int argc, char* argv[])
{
try
{
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query("localhost", "62000");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::endpoint endpoint = *endpoint_iterator;
std::cout << endpoint << "\n\n";
tcp::socket socket(io_service);
boost::asio::connect(socket, endpoint_iterator);
for (;;)
{
boost::array<char, 128> buf;
boost::system::error_code error;
size_t len = socket.read_some(boost::asio::buffer(buf), error);
if (error == boost::asio::error::eof)
break; // Connection closed cleanly by peer.
else if (error)
throw boost::system::system_error(error); // Some other error.
std::cout.write(buf.data(), len);
}
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
std::cout << "\n\n";
system("pause");
return 0;
}
It turns out my router won't accept connections from the internet (using external IP) if the request comes from my local network.
As long as the request isn't coming from my local network, the client will connect to the server without problems.
If I want to run both client and server on my machine, I must use my internal IP (127.0.0.1 or my internal network IP).
If someone else wants to connect to my server from outside my local network, it will work fine. But machines inside my local network won't be able to access the server using external IP, only internal IP.
I never saw this happen. But at least it doesn't affect the functionality of my program.

Cannot get boost::asio simple synchronous server tutorial program to work -- connection refused

I am following the Introduction to Sockets boost::asio tutorial here, called a A synchronous TCP daytime client. I have copied the code exactly, but then moved them into Server.cpp and Client.cpp.
Server.cpp
#include <ctime>
#include <iostream>
#include <string>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
std::string make_daytime_string()
{
std::time_t now = time(0);
return ctime(&now);
}
int main()
{
try {
std::cout << "Initiating server..." << std::endl;
boost::asio::io_service io;
tcp::acceptor acceptor (io, tcp::endpoint(tcp::v4(), 8889));
for (;;) {
tcp::socket socket (io);
acceptor.accept(socket);
std::string message = make_daytime_string();
boost::system::error_code ignored_error;
boost::asio::write(socket, boost::asio::buffer(message), ignored_error);
}
}
catch (std::exception & e) {
std::cerr << e.what() << std::endl;
}
return 0;
}
Client.cpp
#include <boost/array.hpp>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
int main(int argc, char * argv[])
{
boost::asio::io_service io;
// Daytime
try {
if (argc != 2) {
std::cerr << "Usage: client <host>" << std::endl;
return 1;
}
tcp::resolver resolver (io);
tcp::resolver::query query (argv[1], "daytime");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::socket socket (io);
boost::asio::connect(socket, endpoint_iterator);
for (;;) {
boost::array<char, 128> buffer;
boost::system::error_code error;
size_t len = socket.read_some(boost::asio::buffer(buffer), error);
if (error == boost::asio::error::eof) {
break; // Connection closed cleanly by peer.
}
else if (error) {
throw boost::system::system_error(error); // Some other error.
}
std::cout.write(buffer.data(), len);
}
}
catch (std::exception & e) {
std::cerr << e.what() << std::endl;
}
return 0;
}
First I run the server:
$ ./server
Initiating server...
Then I run the client:
$ ./client localhost
connect: Connection refused
Since I am brand new to sockets and boost, unfortunately I am stuck on finding a solution to this connection refused error message.
Your server is running on port 8889.
Your client connects on port 13 (a.k.a. "daytime").
This will not work. For the obvious reason.
Note if you do decide to run the server on port 13, you need administrative privileges for that.

reading from boost asio socket and printing to terminal

I want to use boost asio sockets to send a message from the server to the client and then print it out to the client terminal. I am trying to send the message "hello". It doesn't work. How can i fix this?
Thanks!
client:
#include <boost/asio.hpp>
#include <iostream>
#include <string>
using namespace std;
int main (int argc, char* argv[]) {
try {
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver::query query("localhost", "41005");
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::iterator destination = resolver.resolve(query);
boost::asio::ip::tcp::resolver::iterator end ;
boost::asio::ip::tcp::endpoint endpoint;
while ( destination != end ) {
endpoint = *destination++;
std::cout<<endpoint<<std::endl;
}
boost::asio::ip::tcp::socket socket(io_service);
socket.connect(endpoint);
boost::array< char, 128 > buf;
boost::system::error_code error;
std::size_t length = boost::asio::read(socket, boost::asio::buffer(buf, 512), boost::asio::transfer_all(), error);
cout << length;
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
server:
#include <boost/asio.hpp>
#include <iostream>
#include <string>
using namespace std;
int main () {
try {
boost::asio::io_service io_service;
boost::asio::ip::tcp::acceptor acceptor(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 41005));
for (; ;) {
std::cout<<"Listening to"<<std::endl;
boost::asio::ip::tcp::socket socket(io_service);
acceptor.accept(socket);
std::string message = "hello";
boost::system::error_code ignored_error;
boost::asio::write(socket, boost::asio::buffer(message), boost::asio::transfer_all(), ignored_error);
}
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
classic error: the "acceptor.accept" method is a blocking call, so the hello part is never called.
Our COut friend would help you, as allways:
...
std::cout<<"Sending hello"<