مكتبة مقبس C++ مستقلة عن النظام الأساسي مع دعم SSL شفاف (وبعض الأشياء الأخرى).
احصل عليه هنا: [مكتبات Windows x64 الثابتة والمشتركة مع دعم SSL] أو [لا يوجد دعم SSL]
# 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
. يقوم الأول بإنشاء مثيل لخادم يقوم بإنشاء مؤشر ترابط واحد لكل عميل (باستخدام الإدخال/الإخراج المحظور)، والثاني بإنشاء خادم ببنية أكثر قابلية للتطوير، باستخدام نمط المفاعل (يتم تقديم العديد من العملاء لكل مؤشر ترابط باستخدام الإدخال/الإخراج غير المحظور).
# 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 ();
}
قريبًا... (قيد التطوير/إعادة البناء، حاليًا يعمل كمكتبة فقط...)