select_echo_server

来源:互联网 发布:吊带承重数据 编辑:程序博客网 时间:2024/05/20 03:43

select

server.c

#include <stdio.h>#include <unistd.h>//fork#include <sys/types.h>#include <sys/socket.h>#include <errno.h>//peeor#include <stdlib.h>//exit()#include <arpa/inet.h>//inet_pton#include <sys/wait.h>//waitpid#define MAX_SIZE 100/*当fork时,必须捕获SIGCHLD信号 * 捕获信号,必须处理被中断的系统调用 * SIGCHLD信号处理函数必须正确编写,不能留下僵尸进程 */void client_handle(int fd){    char buf[MAX_SIZE];    int len;    while(1)    {        len = read(fd,buf,MAX_SIZE);        buf[len]='\0';        printf("recv %s\n",buf);        if(len > 0)            write(fd,buf,len);        else if (len < 0 && errno == EINTR)            continue;        else if (len == 0)        {            printf("recv FIN from client\n");            return ;        }        else perror("read error");    }}void child_handle(int sigo){    int status;    while(1)    {        pid_t pid = waitpid(-1,&status,WNOHANG);        if(pid > 0)            printf("child %d terminal\n",pid);        else return;    }}int main(){    int listen_fd = socket(AF_INET,SOCK_STREAM,0);    if(listen_fd < 0)        perror("listen error");    struct sockaddr_in listen_sock;    bzero(&listen_sock,sizeof(listen_sock));    listen_sock.sin_family = AF_INET;    listen_sock.sin_port = htons(12345);    int err = inet_pton(AF_INET,"127.0.0.1",(char *)&listen_sock.sin_addr);    if(err < 0)        perror("inet_pton error");    err = bind(listen_fd,(struct sockaddr *)&listen_sock,sizeof(listen_sock));      if(err < 0)        perror("bind error");    err = listen(listen_fd,5);    if(err < 0)        perror("listen error");    signal(SIGCHLD,child_handle);    while(1)    {        struct sockaddr_in client_addr;        int client_addr_len;        int client_fd = accept(listen_fd,(struct sockaddr *)&client_addr,&client_addr_len);        if(errno == EINTR)            continue;        pid_t pid = fork();        if(pid > 0)        {            close(client_fd);        }        else        {            close(listen_fd);            client_handle(client_fd);            exit(1);        }    }    return 0;}
#include <sys/socket.h>#include <string.h>#include <stdlib.h>#include <errno.h>#include <sys/types.h>#include <stdio.h>//fileno#include <arpa/inet.h>//htons#include <signal.h>#include <sys/time.h>//select#include <sys/select.h>//select/* * 缺点:stdio是有缓冲的,select不知道stdio使用了缓冲区,他只是从read系统调用的角度指出是否有数据可读 * 可能发送的速率远大于接收,当发送结束后仍就有数据要接收,所以当发送结束时shutdown(fd,SHUT_WR),FD_CLR(fileno(stdio),&rset) */int max(int a, int b){    return a>b?a:b;}#define MAX_SIZE 100 void send_echo_fun(int fd) {    char buf_snd[MAX_SIZE];    char buf_rcv[MAX_SIZE];     int len;     fd_set rset;    FD_ZERO(&rset);    while(1)    {        FD_SET(fileno(stdin),&rset);        FD_SET(fd,&rset);        int maxfd = max(fileno(stdin),fd) + 1;        select(maxfd,&rset,NULL,NULL,NULL);        if(FD_ISSET(fd,&rset))        {            int len = read(fd,buf_rcv,MAX_SIZE);              if(len == 0)            {                printf("rcv fin from peer\n");                printf("tag\n");                return;            }            buf_rcv[len]='\0';            printf("%s\n",buf_rcv);        }        if(FD_ISSET(fileno(stdin),&rset))        {            char *s = fgets(buf_snd,MAX_SIZE,stdin);            if(s == NULL)                break;            int n = strlen(buf_snd)-1;            if(n>0)            {                write(fd,buf_snd,n);            }        }    }}int main(){    int client_fd ;    client_fd = socket(AF_INET,SOCK_STREAM,0);    if(client_fd < 0)        perror("socket error");    struct sockaddr_in server_sock;    server_sock.sin_family = AF_INET;    server_sock.sin_port = htons(12345);    int err = inet_pton(AF_INET,"127.0.0.1",&server_sock.sin_addr);    if(err != 1)        perror("inet_pton error");    err = connect(client_fd,(struct sockaddr *)&server_sock,sizeof(server_sock));    if(err == 0)        printf("connect ok\n");    send_echo_fun(client_fd);    close(client_fd);    return 0;}
0 0
原创粉丝点击