我在C中编写服务器和两个客户端。一个客户端是接收命令的“从属”类型的客户端,另一个是发送命令的“主”类型客户端。我希望将多个从站实例连接到服务器,并能够通过服务器从主站向特定从站发送命令。
我的问题是如何指定要将命令发送到的客户端?
这是我服务器的一个非常基本的例子(没有错误检查) 我的实际服务器有错误检查等等,但发布时间过长(并且无论如何都不会为任何人编译,因为我的项目中存在对其他文件的依赖)
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
int server_portnumber = 51739;
int main() {
int listenFD;
int connectFD;
socklen_t length;
struct sockaddr_in s1;
struct sockaddr_in s2;
listenFD = socket( AF_INET , SOCK_STREAM , 0 );
memset( &s1, 0, sizeof( s1 ) );
s1.sin_family = AF_INET;
s1.sin_addr.s_addr = INADDR_ANY;
s1.sin_port = server_portnumber;
bind( listenFD , (struct sockaddr*) &s1 , sizeof( s1 ) );
length = sizeof( s1 );
getsockname( listenFD , (struct sockaddr*) &s1 , &length );
listen( listenFD , 512 );
signal( SIGCHLD , SIG_IGN );
while(1) {
length = sizeof( s2 );
connectFD = accept( listenFD , (struct sockaddr*) &s2 , &length );
if( !fork() ){
close( listenFD );
int select = 0;
while( read( connectFD , &select, sizeof( int ) ) ) {
switch( select ) {
case 10:
// opcode
break;
case 20:
// command
break;
default:
break;
}
}
close( connectFD );
exit(0);
}
}
}
答案 0 :(得分:1)
您需要为每个客户端分配一个ID,让主人以某种方式了解这些ID,并为服务器提供一些从ID映射到套接字的方法。
“某种方式”非常模糊......因为有无限的可能性,所有这些都有不同的设计含义。例如,您可以通过以下方式引用客户:
对于其中大部分内容,您必须告诉主人新的客户端是否具有相关ID。当主人想要向特定客户发送消息时,它会发回该ID,这意味着你需要某种地图(只是一个数组,如果它像fd或自动索引一样简单;可能是哈希表或平衡树(如果它是一些任意字符串)来查找ID并获取fds。
为了使这个更具体,请考虑一个聊天协议,比如IRC,但更简单。
当您第一次连接时,没有人可以与您通话,您也无法与其他人通话。
服务器维护一个哈希表,将昵称映射到套接字fds。
当您发送/nick NICKNAME
命令时,其中NICKNAME
是一个有效的昵称(例如,任何其他人没有使用的最多20个字母和数字的序列),服务器会添加一个条目哈希表将您的昵称映射到您的fd,并向每个说“NICKNAME已加入”的人发送消息。
发送/msg NICKNAME MESSAGE
命令时,服务器在哈希表中查找NICKNAME
。如果找到它,它会将MESSAGE发送到具有相应fd的套接字。