多线程udp服务器/客户端
我刚刚使用 udp 创建了一点可靠的文件传输,但它只能处理一个客户端。所以我考虑使用 fork() 让服务器处理多个客户端。但是,我真的不知道如何继续。现在,我知道我不需要更改客户端,服务器将完成这些肮脏的工作。非常感谢任何有关如何解决该问题的想法/想法。 诗。我是这样开始的:
void sigchldAction(int sig) {
while (waitpid(-1, 0, WNOHANG) > 0) {
;
}int main(int argc, char *argv[]) {
return;
} //This is my function that waits for all the processes
这是我的服务器:
int main(int argc, char *argv[]) {
struct sockaddr_in serv_addr;
int port_number, socket_fd;
port_number = atoi(argv[1]);
signal(SIGCHLD, sigchldAction);
if ((socket_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) exit(EXIT_FAILURE);
if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR,
(const void *)&optval, sizeof(int)) < 0) exit(EXIT_FAILURE);
bzero((void *)&serv_addr, sizeof(struct sockaddr_in));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(port_number);
if (bind(socket_fd, (struct sockaddr *)&serv_addr,
sizeof(struct sockaddr_in)) < 0) exit(EXIT_FAILURE);
pid_t child_pid;
while (1) {
child_pid = fork();
switch (child_pid) {
case -1:
perror("Fork() Failed. \n");
exit(EXIT_FAILURE);
break;
case 0:
process_request(socket_fd);
exit(EXIT_SUCCESS);
break;
case 1:
close(socket_fd);
break;
}
}
close(socket_fd);
exit(EXIT_SUCCESS);
}
然后我的 process_request 函数负责处理任何传入的数据。
I just created a little reliable file transfer using udp but it only handles one client. So I thought about using fork() to get the server to handle multiple clients. But, i don't really know how to proceed. For now, I know I don't need to change the client side and the server is the one that will do the dirty work. Any thought/ideas on how to tackle that problem is greatly appreciated.
Ps. here is how I started:
void sigchldAction(int sig) {
while (waitpid(-1, 0, WNOHANG) > 0) {
;
}int main(int argc, char *argv[]) {
return;
} //This is my function that waits for all the processes
Here is my server:
int main(int argc, char *argv[]) {
struct sockaddr_in serv_addr;
int port_number, socket_fd;
port_number = atoi(argv[1]);
signal(SIGCHLD, sigchldAction);
if ((socket_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) exit(EXIT_FAILURE);
if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR,
(const void *)&optval, sizeof(int)) < 0) exit(EXIT_FAILURE);
bzero((void *)&serv_addr, sizeof(struct sockaddr_in));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(port_number);
if (bind(socket_fd, (struct sockaddr *)&serv_addr,
sizeof(struct sockaddr_in)) < 0) exit(EXIT_FAILURE);
pid_t child_pid;
while (1) {
child_pid = fork();
switch (child_pid) {
case -1:
perror("Fork() Failed. \n");
exit(EXIT_FAILURE);
break;
case 0:
process_request(socket_fd);
exit(EXIT_SUCCESS);
break;
case 1:
close(socket_fd);
break;
}
}
close(socket_fd);
exit(EXIT_SUCCESS);
}
Then my process_request function takes care of any incoming data.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您使用 UDP,则没有连接;这是一个无连接协议。
如果您要分叉,则需要执行 ftpd 的操作,并告诉远程客户端在与原始端口不同的端口上发送分叉的子数据包(当然,让子数据包在该端口上接收)。
If you're using UDP you don't have a connection; it's a connectionless protocol.
If you're going to fork, you'd need to do what ftpd does and tell the remote client to send the forked child packets on a different port than the original one (and of course have the child receive on that port).
您最好避免使用
fork()
,并简单地根据源地址区分客户端。采取的基本方法是获取当前描述应用程序层连接的所有变量(例如当前文件、文件中的当前位置、客户端地址)并将它们提升到
struct
中。然后,您为每个客户端创建此struct
的一个实例。使用
recvfrom()
而不是recv()
来侦听传入数据包。这将提供客户端的地址(请注意,这种意义上的地址应包括客户端的端口号) - 然后您可以查找每个客户端struct
的适当实例。You're better off avoiding
fork()
, and simply distinguishing the clients based on their source address.The basic approach to take is to take all of your variables that currently describe the application-layer connection (eg. current file, current position within the file, client address) and hoist those into a
struct
. You then create one instance of thisstruct
per client.Use
recvfrom()
rather thanrecv()
to listen for incoming packets. This will supply the client's address (note that address in this sense should include the client's port number) - you can then look up the appropriate instance of the per-clientstruct
.