【发布时间】: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& new_socket) const { ... }和std::string ServerSocket::get_ip(ServerSocket& sock) const { ... },因为它们不应修改Socket。 -
谢谢你,我会考虑学习 Asio,也感谢 const 的建议:)
标签: c++ api class sockets stream