|
楼主 |
发表于 2003-4-9 19:56:07
|
显示全部楼层
呵呵,说起来是一句话,做起来还是要费点功夫。改进后的程序还有两个问题没有解决。一。执行命令有迟滞。上一步的执行结果要下一次才能看到。二。在同时连接多个client的情况下,如果有一个client退出,server会中止。
改进后的socket_server.c如下:
- #include<sys/types.h>
- #include<sys/socket.h>
- #include<sys/time.h>
- #include<sys/ioctl.h>
- #include<stdio.h>
- #include<netinet/in.h>
- #include<arpa/inet.h>
- #include<unistd.h>
- void exec_command(int c_sockfd)
- {
- char buf[256]; /* 用BUFSIZ太大了(有8192个字节),改成256。呵呵。。。 */
- int n;
-
- /* 把stdout和stderr重定向到sockfd */
- close(1);
- dup(c_sockfd);
- close(2);
- dup(c_sockfd);
-
- n = read(c_sockfd, buf, sizeof(buf));
-
- if (n > 0) {
-
- //printf("%d server %s", n, buf);
- system(buf);
- }
- }
- int main()
- {
- int server_sockfd, client_sockfd;
- int client_len;
- struct sockaddr_in server_address;
- struct sockaddr_in client_address;
- //char buf[BUFSIZ];
- int result;
- fd_set readfds, testfds;
- server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
- server_address.sin_family = AF_INET;
- server_address.sin_addr.s_addr = htonl(INADDR_ANY);
- server_address.sin_port = htons(19734);
- client_len = sizeof(client_address);
- bind(server_sockfd, (struct sockaddr *) &server_address, sizeof(server_address));
-
- listen(server_sockfd, 5);
- FD_ZERO(&readfds);
- FD_SET(server_sockfd, &readfds);
-
- while (1) {
- char ch;
- int fd;
- static int max_fd = 10; /* 为了节省资源,这里最大只使用了10个文件描述符。 */
- int n;
-
- testfds = readfds;
- printf("server waiting\n");
-
- result = select(max_fd, &testfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0);
-
- if(result < 1) { /* 如果小于1 ,说明select执行出错。 */
- perror("server");
- exit(1);
- }
-
- for(fd = 0; fd < max_fd; fd++) {
-
- if(FD_ISSET(fd, &testfds)) {
- //printf("checking%d serverfd%d", fd, server_sockfd);
- if(fd == server_sockfd) { /* 如果是来自server,则产生新的连接。 */
- client_sockfd = accept(server_sockfd, (struct sockaddr *) &client_address, &client_len);
- FD_SET(client_sockfd, &readfds);
- if(client_sockfd > max_fd) max_fd = client_sockfd;
- printf("adding client on fd %d\n",client_sockfd);
- }
- else { /* 检查有没有输入,如果没有,则关闭连接; 如果有,则执行命令。 */
- ioctl(fd, FIONREAD, &n);
-
- if(n == 0) {
- close(client_sockfd);
- FD_CLR(fd, &readfds);
- printf("removing client on fd %d\n", fd);
- }
- else {
- exec_command(fd);
- //printf("exec_fd:%d\n", fd);
- }
- }
-
- }
- }
- }
- }
复制代码 |
|