c语言怎么在服务器端查询进程列表,C语言 在服务器端识别客户端的方法

这篇博客讨论了在C创建的客户端-服务器应用中如何安全地管理用户会话。作者提出了两种方法:一是使用客户端IP和账户ID映射,二是使用随机生成的密钥。然而,IP可能会因NAT或同一计算机上的多个客户端而产生混淆,而随机密钥方案则存在会话劫持的风险。建议使用更安全的策略,如套接字句柄或线程本地存储来关联会话数据,确保安全性。
摘要由CSDN通过智能技术生成

我正在用C创建客户端 – 服务器应用程序.服务器将接受来自多个客户端的请求每个客户在服务器上创建个人帐户.身份验证后,我知道客户端使用特定的ip登录到特定帐户.现在我想确定哪些请求考虑特定帐户,例如:

客户A登录:

username: user

password: pass123

服务器发现这些数据与id = 3的帐户匹配.

现在当这个客户端A发送一些请求时,我希望服务器访问(并最终改变)id = 3的帐户.到目前为止,我已经提出了这两个想法:

>我有一个std :: map,其中key是客户端ip,值是帐户ID.在身份验证之后,服务器将客户端的ip及其帐户ID存储到此映射中,稍后当服务器收到来自客户端的请求时,它会检查它的ip并在映射中查找它.

>我有一个std :: map,其中key是随机生成的key,value是account id.验证后,服务器为此特定客户端生成随机密钥,将此密钥发送给客户端,客户端将其保存以供进一步使用,服务器将此密钥和帐户ID存储在映射中.

我想知道这些是否是处理这类问题的好方法.哪一个更好,还考虑安全性(这对我来说非常重要)?还是有更好的方法?

1) I have a std::map where key is client ip and value is account id. After authentication, server stores client’s ip and it’s account id into this map and later when server receives request from client, it checks it’s ip and looks for it in map.

IP本身是不够的:可以有几个不同的客户端连接来自同一个IP(来自同一台计算机,或来自NAT后面的不同计算机,因此您只能看到NAT IP).如果您需要基于IP的唯一密钥,则需要使用客户端的IP /端口元组.

2) I have a std::map where key is randomly generated key and value is account id. After authentication, server generates random key for this specific client, sends this key to client, client saves it for further use, server stores this key and account id in map.

这是非常危险的:什么禁止客户端发送另一个客户端的“会话ID”而不是他的一个,从而劫持了另一个客户端的会话?这与您可能想要阅读的HTTP会话劫持问题完全相同.简而言之:如果你能避免它,就不要这样做.

其他可能的方案:

>仍然使用std :: map,您可以使用套接字句柄作为密钥:它在服务器上必然是唯一的,因此不会产生混淆,并且它使您无需在每条消息中检索客户端的IP /端口.

>如果您的服务器使用旧的“每个连接一个线程”模型,那么您不必跳过这些环节.只需将会话数据与线程本地存储变量相关联即可.或者,几乎所有线程库都允许您将参数传递给线程,这可用于将特定数据与您的线程相关联(请参阅下面的示例).

>如果您的服务器使用旧的“每个连接一个进程”模型(fork),那么它就更容易了,每个进程都有自己的变量,因此您没有任何特殊操作.

不幸的是,只要我们不知道你的服务器使用的模型(线程,分叉,选择,aio,……?),你的问题就是开放式的,所以你很难给出明确的答案.

如果您使用的是线程模型,这里(大致)我通常如何做(C 11线程,但任何其他线程库也可以这样做):

class ClientSession {

public:

ClientSession(int sock)

: m_sock(sock),

m_thread(&ClientSession::threadFunction, this)

{

}

private:

int m_sock;

WhateverType m_someSessionVariable;

std::thread m_thread; // the thread object should be declared last so that

// it is initialised last in the constructor, thus avoiding race conditions

// during the initialisation (you really don't want the thread to access

// your member variables if they are not yet initialised!)

static void threadFunction(ClientSession* object) {

object->threadMethod();

}

void threadMethod() {

// handle your connection

// the current ClientSession object (this) *is* your session

// put whatever you want in it, eg. m_someSessionVariable

}

};

//...

int sock_client = TEMP_FAILURE_RETRY(accept(sock_server, 0, 0));

if (sock_client >= 0)

new ClientSession(sock_client);

警告:显然这段代码有缺陷,它永远不会破坏ClientSession对象,因此它有内存泄漏但我的目的是展示如何将一个线程与一个特定的会话对象相关联,我将留给你管理对象的生命周期取决于您的确切架构和需求.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值