ไลบรารีซ็อกเก็ต C++ อิสระของแพลตฟอร์มพร้อมการรองรับ SSL แบบโปร่งใส (และอื่นๆ อีกมากมาย)
รับได้ที่นี่: [Windows x64 static & shared libraries with SSL support] หรือ [no SSL support]
# include " libsockets.h "
void client () {
socks::ClientSocket clientSocket;
if (clientSocket. connectTo ( " 127.0.0.1 " , " 10000 " ) == 0 ) {
std::string hello = " Hello World " ;
clientSocket. sendData (hello. c_str (), hello. size ());
}
};
int main () {
client ();
};
# include " libsockets.h "
void server () {
socks::ServerSocket serverSocket;
serverSocket. listenForConnections ( " 127.0.0.1 " , " 10000 " );
socks::ClientSocket clientSocket = serverSocket. acceptConnection ();
char buf[ 512 ];
auto len = clientSocket. receiveData (buf, 512 );
if (len > 0 ) {
buf[len]= 0 ;
std::cout << buf << std::endl;
}
};
int main () {
server ();
};
$ > ./server &
$ > ./client
socks::makeThreaded[SSL]Server
& socks::makeMultiplexed[SSL]Server
) # include " libsockets.h "
class MyContext {
public:
int value; // whatever context you need to maintain
};
void onReceive (socks::Context<MyContext> &context, std::istream &inp, std::ostream &outp) {
std::string word;
while (inp >> word)
outp << context. getContext (). value ++ << " " << word << std::endl;
};
void onConnect (socks::Context<MyContext> &context, std::istream &inp, std::ostream &outp) {
context. getContext (). value = 0 ;
outp << " Hello " << std::endl;
};
int main () {
auto myServer = socks::factory::makeThreadedServer<MyContext>(
onReceive,
onConnect /* ,
onDisconnect,
afterWrite
*/
); // onReceive is mandatory, onConnect, onDisconnect & afterWrite are optional
myServer. listen ( " 127.0.0.1 " , " 10000 " ); // serves
};
คุณสามารถแทนที่ socks::factory::makeThreadedServer
ด้วย socks::factory::makeMultiplexedServer
ขั้นแรกสร้างอินสแตนซ์เซิร์ฟเวอร์ที่สร้างหนึ่งเธรดต่อไคลเอ็นต์ (โดยใช้การบล็อก I/O) ขั้นที่สองสร้างอินสแตนซ์เซิร์ฟเวอร์ด้วยสถาปัตยกรรมที่ปรับขนาดได้มากกว่า โดยใช้รูปแบบรีแอคเตอร์ (ไคลเอ็นต์หลายรายการให้บริการต่อเธรดโดยใช้ I/O ที่ไม่บล็อก)
# include " libsockets.h "
constexpr size_t bufferSize = 4096 ;
int main () {
socks::DatagramSocket datagramSocket;
datagramSocket. bindSocket ( " 0.0.0.0 " , " 10000 " );
char buffer[bufferSize];
std::pair< int , socks::SocketAddress> ret = datagramSocket. receiveFrom (buffer, bufferSize);
// ret = pair<bytes received, sender address>
if (ret. first > 0 ) {
auto peer = std::move (ret. second );
std::string reply = " received " + std::to_string (ret. first ) + " bytes " ;
datagramSocket. sendTo (peer, reply. c_str (), reply. size ());
} else {
std::cerr << " error receiving. " << std::endl;
}
}
คุณยังสามารถเปลี่ยน socks::DatagramSocket
เป็นซ็อกเก็ตดาตาแกรม 'เชื่อมต่อ' และใช้อินเทอร์เฟซของ socks::ClientSocket
socks::ClientSocket clientSocket = datagramSocket.makeClientSocket(peer);
/*
* from this point on 'datagramSocket' cannot be used anymore,
* its implementation has been moved to 'clientSocket'.
*/
หรือ
socks::ClientSocket clientSocket = datagramSocket.makeClientSocket(host, port); // same here
มันเป็น socks::ClientSocket
ที่อยู่ในคลาส std::iostream
# include " libsockets.h "
int main () {
socks::SocketStream socketStream;
if (socketStream. connectTo ( " 127.0.0.1 " , " 10000 " ) == 0 ) {
std::string buf;
std::getline (socketStream, buf); // receiving data
std::cout << buf << std::endl;
socketStream << " message received. " << std::endl; // transmitting data
} else {
std::cerr << " error connecting. " << std::endl;
}
}
เพียงแทนที่การประกาศ:
socks::ClientSocket clientSocket = socks::factory::makeSSLClientSocket;
socks::ServerSocket serverSocket = socks::factory::makeSSLServerSocket;
socks::SocketStream socketStream = socks::factory::makeSSLSocketStream;
socks::Server server = socks::factory::makeThreadedSSLServer<...>(...);
socks::Server server = socks::factory::makeMultiplexedSSLServer<...>(...);
แค่นั้นแหละ. สำหรับ socks::ServerSocket
และ socks::Server
คุณจะต้องมีใบรับรองและไฟล์คีย์ด้วย (ชื่อเริ่มต้นคือ 'cert.pem' และ 'key.pem') หากต้องการสร้างใบรับรองการทดสอบและไฟล์คีย์:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
เนมสเปซนี้มีวิธีการจากโรงงานทั้งหมดของไลบรารี
ตัวอย่างที่ซับซ้อนมากขึ้น: การใช้งานเซิร์ฟเวอร์ FTP ที่เรียบง่ายแต่ทำงานได้อย่างสมบูรณ์โดยใช้ libsockets (รวมถึงการรองรับ SSL, โหมดพาสซีฟ, ประวัติย่อ และการสนับสนุน FXP) มีการโทรกลับการรับรองความถูกต้องสำหรับผู้ใช้ คุณยังสามารถลงทะเบียนคำสั่ง SITE แบบกำหนดเองได้
คุณสามารถลองได้: ไบนารี่แบบคงที่ของ Windows x64
AuthenticationFunction FTPClientInfo::authenticate =
[]( const std::string &username, const std::string &password, FTPClientInfo& clientInfo) {
/*
* in here a user profile can be loaded into 'clientInfo'
* upon authentication in order to define, for example,
* a home dir, chroot, etc.
*/
return authService. authenticate (username, password);
};
int main ( int argc, char **argv) {
FTPServer ftpServer;
// SITE CLIENT COUNT
ftpServer. registerSiteCommand (
" CLIENT " ,
[&ftpServer]( const std::string ¶ms, FTPClientInfo &clientInfo) {
std::stringstream ss (params);
std::string p1;
ss >> p1;
std::transform (p1. begin (), p1. end (), p1. begin (), ::toupper);
if (p1 == " COUNT " )
return " 200 There is/are " + std::to_string (ftpServer. getClientCount ()) + " client(s) online. " ;
else
return std::string ( " 501 Invalid SITE CLIENT parameter. " );
});
ftpServer. start ();
}
เร็วๆ นี้... (อยู่ระหว่างการพัฒนา/รีแฟคเตอร์ ปัจจุบันทำงานเป็นห้องสมุดเท่านั้น...)