【发布时间】:2017-12-03 16:44:08
【问题描述】:
我有一台服务器,它应该允许一个客户端一次连接、执行命令然后关闭。服务器保留“当前连接的”IP 地址的数组列表,以便知道从谁那里接受命令。 问题是我有两个运行在相似 IP 地址上的客户端被视为同一个客户端。
示例: 客户端 A 的 IP 地址为 255.255.255.153。我告诉它连接,一切正常。 客户端 B 的 IP 地址为 255.255.255.156。我告诉它连接,服务器说它已经连接。
我的 strcmp 不正确吗?是别的吗?请帮忙。
// Variable Declarations
int SIZE = 10; // Max number of agents
char *agents[SIZE], // List of current connections
*times[SIZE]; // List of connection times
char buffer[MAXBUF];
int bytes_read = 0;
int total_bytes_read = 0;
int found = 0, // Bool flag
i;
struct tm ts;
struct timeval connected[SIZE],
current,
difference;
time_t TIME;
// Initialize array to NULL
for(i = 0; i < SIZE; i++) {
agents[i] = NULL;
}
// Infinite Loop
while (true) {
struct sockaddr_in client;
int clientSocket;
socklen_t clientLength = sizeof(client);
memset(&client, 0, clientLength);
clientSocket = accept(sd, (struct sockaddr *)&client, &clientLength);
memset(buffer,0,MAXBUF);
bytes_read = read(clientSocket, buffer, MAXBUF);
if (bytes_read < 0)
break;
fprintf(stdout,"\nRead %d bytes: [%s]\r\n", bytes_read,buffer);
char *connectedIP = inet_ntoa(client.sin_addr);
// Option 1:
if ((strcmp(buffer, "#JOIN")) == 0) { // Join list of connected agents
found = 0;
// Get current time for log
TIME = time(NULL);
ts = *localtime(&TIME);
// Print message to log
char buf[80];
strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts);
fprintf(log, "%s: Received a \"#JOIN\" action from agent \"%s\"", buf, connectedIP);
fprintf(log, "\n\n");
fflush(log);
printf("\n%s Joining", connectedIP);
fflush(stdout);
// Handle #JOIN request appropriately
for (i = 0; i < SIZE; i++) {
printf("\nAgent[%d] == %s", i, agents[i]);
if (agents[i] == NULL) {
}
else if (strcmp(agents[i], connectedIP) == 0){ // Agent found in list
found = 1;
printf("\n%s is equal to %s", agents[i], connectedIP);
fflush(stdout);
// Write to agent
char response[] = "#ALREADY MEMBER";
write (clientSocket, response, strlen(response));
// Get time for log
TIME = time(NULL);
ts = *localtime(&TIME);
// Write to log
char buf[80];
strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts);
fprintf(log, "%s: Responded to agent \"%s\" with \"#ALREADY MEMBER\"", buf, connectedIP);
fprintf(log, "\n\n");
fflush(log);
i = SIZE;
}
}
if (found == 0) { // Save IP to list/queue
for(i = 0; i < SIZE; i++) {
if (agents[i] == NULL) {
// Save IP to array
agents[i] = connectedIP;
printf("\nagents[%d] = %s\n", i, connectedIP);
fflush(stdout);
// Save time to arrays
gettimeofday(&connected[i], NULL);
TIME = time(NULL);
times[i] = TIME;
ts = *localtime(&TIME);
// Write to log
char buf[80];
strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts);
fprintf(log, "%s: Responded to agent \"%s\" with \"#OK\"", buf, connectedIP);
fprintf(log, "\n\n");
fflush(log);
// Write to agent
char response[] = "#OK";
write (clientSocket, response, strlen(response));
i = SIZE;
}
}
}
memset(&client, 0, clientLength);
}
【问题讨论】:
-
你没有展示
agents数组是如何定义的,AFAICS。如果您已正确定义它并将 IPv4 地址存储为字符串,strcmp()应该没问题。但是您需要允许 16 个字节用于存储每个地址; 3 个单位的“192”。和“192\0”之一。因此,很大程度上取决于您未显示的代码。请阅读有关如何创建 MCVE (minimal reproducible example) 的信息。你展示的不是 MCVE。 -
添加了“代理”声明,对评论感到抱歉。修好了。
-
你存储
agents[i] = connectedIP;再一次,一个未声明的变量,但你可能为所有代理使用相同的空间,所以如果你遍历连接的代理,打印名称,你会发现它们都一样。我希望那里有strdup(connectedIP)之类的东西。但它仍然不是 MCVE,因此人们仍然不方便尝试帮助您。 -
conectedIP 的定义显示在
char *connectedIP = inet_ntoa(client.sin_addr);我会看看strdup -
我还建议不要仅根据他们的 IP 地址来识别您的客户。从一个 IP 打开多个连接可能有正当的理由,例如 NAT(可能使用虚拟机)、测试场景以及您的高级用户想出的任何其他内容。 IP地址作为唯一身份验证者也很糟糕。