【问题标题】:c++ socket stream apic++ 套接字流api
【发布时间】:2011-04-30 00:45:07
【问题描述】:

我正在使用看起来很不错的 API 来处理此处的流式套接字: http://www.pcs.cnu.edu/~dgame/sockets/socketsC++/sockets.html.

我在访问已连接用户的 IP 时遇到问题,因为它是在另一个类“ServerSocket”中使用的“Socket”类的私有成员。我的程序看起来和演示完全一样,只是它分叉了进程。

// libraries
#include <signal.h>
#include <string>
#include <iostream>

// headers
#include "serversocket.hpp"
#include "socketexception.hpp"
#include "config.hpp"

using namespace std;

void sessionHandler( ServerSocket );


int main ( int argc, char** argv )
{
    configClass config; // this object handles command line args
    config.init( argc, argv ); // initialize config with args

    pid_t childpid; // this will hold the child pid

    signal(SIGCHLD, SIG_IGN); // this prevents zombie processes on *nix

    try
    {
        ServerSocket server ( config.port ); // create the socket

        cout << "server alive" << "\n";
        cout << "listening on port: " << config.port << "\n";

        while ( true )
        {

            ServerSocket new_client; // create socket stream
            server.accept ( new_client ); // accept a connection to the server

            switch ( childpid = fork() ) // fork the child process
            {
            case -1://error
                cerr << "error spawning child" << "\n";
                break;
            case 0://in the child
                sessionHandler( new_client ); // handle the new client
                exit(0); // session ended normally
                break;
            default://in the server
                cout << "child process spawned: " << childpid << "\n";
                break;
            }
        }
    }
    catch ( SocketException& e ) // catch problem creating server socket
    {
        cerr << "error: " << e.description() << "\n";
    }

    return 0;
}


// function declarations

void sessionHandler( ServerSocket client )
{
    try
    {
        while ( true )
        {
            string data;
            client >> data;
            client << data;
        }
    }
    catch ( SocketException& e )
    {
        cerr << "error: " << e.description() << "\n";
    }
}

所以我的问题是,我不能访问当前连接到套接字的客户端的 IP 吗?如果必须针对该功能进行修改,最干净的方法是什么?

感谢您的建议

我能够添加这两个函数,使我只能从 main 范围内获取 IP,如下所示:

server.get_ip(new_client); 但我真正想要的是像这样 new_client.ip();

这是我的 2 个函数,也许你可以进一步帮助我:

std::string Socket::get_ip( Socket& new_socket )
{
  char cstr[INET_ADDRSTRLEN];
  std::string str;
  inet_ntop(AF_INET, &(m_addr.sin_addr), cstr, INET_ADDRSTRLEN);
  str = cstr;
  return str;
}

std::string ServerSocket::get_ip( ServerSocket& sock )
{
    return Socket::get_ip( sock );
}

【问题讨论】:

  • 从性能的角度来看,您不应该为每个客户端 fork() 一个新进程。这有很多开销。您可能希望考虑 Boost.Asio,因为它可以自动处理事件驱动的通信,但对于初学者来说,这是一条陡峭的学习曲线。
  • 考虑将新函数设为const,使它们看起来像:std::string Socket::get_ip(Socket&amp; new_socket) const { ... }std::string ServerSocket::get_ip(ServerSocket&amp; sock) const { ... },因为它们不应修改Socket
  • 谢谢你,我会考虑学习 Asio,也感谢 const 的建议:)

标签: c++ api class sockets stream


【解决方案1】:

您使用的 Socket 类有一个私有数据成员:

sockaddr_in m_addr;

这包含连接到套接字的客户端的信息。您可以通过以下方式获取人类可读的地址:

char str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(m_addr.sin_addr), str, INET_ADDRSTRLEN);

至于你需要做的更改,要么将m_addr设为public(不推荐),要么根据上面的代码示例添加一个可以返回字符串的成员函数。

【讨论】:

  • 谢谢我更进一步,并在我的问题中提供更多细节以及我到目前为止所做的事情
猜你喜欢
  • 1970-01-01
  • 2020-10-20
  • 1970-01-01
  • 2013-02-08
  • 2023-03-18
  • 2014-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多