发新话题
打印

帮忙,linux socket 编程问题

帮忙,linux socket 编程问题

下面代码是在同台PC上运行的,只实现了一个服务端和一个客户端之间的通讯;现在本人想让他们实现一个服务端和多个客户端之间通讯,怎么实现呀?大哥大姐帮帮忙小弟可以吗?
实现是i/o多路复用的方法:
server代码:
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include  <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>

#define MAXDATASIZE 256
#define SERVPORT 3333
#define BACKLOG 1
#define STDIN 0

int main(void)
{
        int sockfd,client_fd;
        int sin_size;
        struct sockaddr_in my_addr, remote_addr;
        char buf[256];
        char send_str[256];
        int recvbytes;
        fd_set rfd_set, wfd_set, efd_set;
        struct timeval timeout;
        int ret;

        if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
                perror("socket";
                exit(1);
        }
       
        bzero(&my_addr, sizeof(struct sockaddr_in));
        my_addr.sin_family=AF_INET;
        my_addr.sin_port=htons(SERVPORT);
        inet_aton("127.0.0.1", &my_addr.sin_addr);

        if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
                perror("bind";
                exit(1);
        }
        if (listen(sockfd, BACKLOG) == -1) {
                perror("listen";
                exit(1);
        }

        sin_size = sizeof(struct sockaddr_in);
        if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size)) == -1) {
                perror("accept");
                exit(1);
        }
        fcntl(client_fd, F_SETFD, O_NONBLOCK);
       
        while (1) {
                FD_ZERO(&rfd_set);
                FD_ZERO(&wfd_set);
                FD_ZERO(&efd_set);
                FD_SET(STDIN, &rfd_set);
                FD_SET(client_fd, &rfd_set);
                FD_SET(client_fd, &wfd_set);
                FD_SET(client_fd, &efd_set);
                timeout.tv_sec = 10;
                timeout.tv_usec = 0;

                ret = select(client_fd + 1, &rfd_set, &wfd_set, &efd_set, &timeout);
                if (ret == 0) {
                        continue;
                }
               
                if (ret < 0) {
                        perror("select error: ");
                        exit(-1);
                }

                if (FD_ISSET(STDIN, &rfd_set)) {
                        fgets(send_str, 256, stdin);
                        send_str[strlen(send_str)-1] = '\0';
                        if (strncmp("quit", send_str, 4) == 0) {
                                close(client_fd);
                                close(sockfd);
                                exit(0);
                        }
                        send(client_fd, send_str, strlen(send_str), 0);
                }
                if (FD_ISSET(client_fd, &rfd_set)) {
                        recvbytes=recv(client_fd, buf, MAXDATASIZE, 0);
                        if (recvbytes == 0) {
                                close(client_fd);
                                close(sockfd);
                                exit(0);
                        }
                        buf[recvbytes] = '\0';
                        printf("client: %s\n", buf);
                        printf("server: ");
                        fflush(stdout);
                }
                if (FD_ISSET(client_fd, &efd_set)) {
                        close(client_fd);
                        exit(0);
                }
        }
}

client客户端代码:
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include  <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>

#define SERVPORT 3333
#define MAXDATASIZE 256
#define STDIN 0

int main(void)
{
        int sockfd;
        int recvbytes;
        char buf[MAXDATASIZE];
        char *str;
        char send_str[MAXDATASIZE];
        struct sockaddr_in serv_addr;
        fd_set rfd_set, wfd_set, efd_set;
        struct timeval timeout;
        int ret;

        if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
                perror("socket");
                exit(1);
        }

        bzero(&serv_addr, sizeof(struct sockaddr_in));
        serv_addr.sin_family=AF_INET;
        serv_addr.sin_port=htons(SERVPORT);
        inet_aton("127.0.0.1", &serv_addr.sin_addr);
        if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1) {
                perror("connect");
                exit(1);
        }
        fcntl(sockfd, F_SETFD, O_NONBLOCK);
        printf("client: ");
        fflush(stdout);
        while (1) {
                FD_ZERO(&rfd_set);
                FD_ZERO(&wfd_set);
                FD_ZERO(&efd_set);
                FD_SET(STDIN, &rfd_set);
                FD_SET(sockfd, &rfd_set);
                FD_SET(sockfd, &efd_set);
                timeout.tv_sec = 10;
                timeout.tv_usec = 0;
                ret = select(sockfd + 1, &rfd_set, &wfd_set, &efd_set, &timeout);
                if (ret == 0) {
                        continue;
                }

                if (ret < 0) {
                        perror("select error: ");
                        exit(-1);
                }

                if (FD_ISSET(STDIN, &rfd_set)) {
                        fgets(send_str, 256, stdin);
                        send_str[strlen(send_str)-1] = '\0';
                        if (strncmp("quit", send_str, 4) == 0) {
                                close(sockfd);
                                exit(0);
                        }
                        send(sockfd, send_str, strlen(send_str), 0);
                }
                if (FD_ISSET(sockfd, &rfd_set)) {
                        recvbytes=recv(sockfd, buf, MAXDATASIZE, 0);
                        if (recvbytes == 0) {
                                close(sockfd);
                                exit(0);
                        }
                        buf[recvbytes] = '\0';
                        printf("server: %s\n", buf);
                        printf("client: ");
                        fflush(stdout);
                }
                if (FD_ISSET(sockfd, &efd_set)) {
                        close(sockfd);
                        exit(0);
                }
        }
}

TOP

引用:
原帖由 jichenxiang008 于 2006-8-22 16:19 发表
下面代码是在同台PC上运行的,只实现了一个服务端和一个客户端之间的通讯;现在本人想让他们实现一个服务端和多个客户端之间通讯,怎么实现呀?大哥大姐帮帮忙小弟可以吗?
实现是i/o多路复用的方法:
server代码:
# ...
在Server上,每次得到客户端的连接后,
fork()一个子进程来专门处理该客户端的请求,也可以采用线程的方式。
参考Unix网络编程!

TOP

发新话题