Linux网络编程echo多线程服务器

echo_server服务器多线程版本

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <memory.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <sys/select.h>
#include <poll.h>
#include <pthread.h>

int sockfd;

void sign_handler(int signo)
{
    pid_t pid;
    int stat;
    if(signo==SIGINT)
    {
        printf("echo server close\n");
        close(sockfd);
        exit(1);
    }
    if(signo==SIGCHLD){
        printf("client close\n");
        wait(0);
    }
    return;
}
void out_fd(int fd)
{
    struct sockaddr_in arr;
    socklen_t len=sizeof(arr);
    if(getpeername(fd,(struct sockaddr*)&arr,&len)<0){
        perror("getpeername fail\n");
        exit(1);
    }
    char ip[16];
    
    memset(&ip,0,sizeof(ip));
    inet_ntop(AF_INET,&arr.sin_addr.s_addr,ip,sizeof(ip));
    printf("%s connected\n",ip);
}
void server_do(int fd)
{
    char buffer[BUFSIZ];
    while(1){
        printf("ready to read\n");
        memset(buffer,0,sizeof(buffer));
        ssize_t size;
        if((size=read(fd,buffer,sizeof(buffer)))<0){
            perror("server child read fail\n");
            break;
        }else if(size==0){
            break;
        }else{
            printf("number of received bytes=%ld\n",size);
            buffer[size-1]='\0';
            printf("%s\n",buffer);
            if(write(fd,buffer,size)<0){
                if(errno==EPIPE){
                    break;
                }
                perror("server child write fail\n");
            }
        }
    }
}
void *doit(void *arg)
{
    int fd=*((int *)arg);
    
    server_do(fd);
    
    close(fd);
    return (void*)0;
}

int main(int argc,char *argv[])
{    
    if(argc<2)
    {
        printf("usage:%s <port>",argv[0]);
        exit(1);
    }
    //注册信号
    if(signal(SIGINT,sign_handler)==SIG_ERR){
        perror("signal sigint error\n");
        exit(1);
    }
    if(signal(SIGCHLD,sign_handler)==SIG_ERR){
        perror("signal sigint error\n");
        exit(1);
    }
    /*create socket*/
    sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd<0){
        perror("socket create fail\n");
        exit(1);
    }
    /*bind socket*/
    struct sockaddr_in serveraddr;
    serveraddr.sin_family=AF_INET;
    serveraddr.sin_port=htons(atoi(argv[1]));
    serveraddr.sin_addr.s_addr=INADDR_ANY;
    if(bind(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr))<0){
        perror("socket bind fail\n");
        exit(1);
    } 
    if(listen(sockfd,10)<0){
        perror("socket listen fail\n");
        exit(1);
    }
    //设置线程的分离属性
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); 

     int *iptr;
     
    while(1){
        iptr=malloc(sizeof(int));
        
        if((*iptr=accept(sockfd,NULL,NULL))>0){
            out_fd(*iptr);
        }
        pthread_t th;
        int err;
        if((err=pthread_create(&th,&attr,doit,iptr))!=0){
            perror("pthread create fail\n");
        }
        pthread_attr_destroy(&attr);    
    }
    return 0;
}

echo_client客户端多线程版本

 

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <memory.h>
#include <signal.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int sockfd;

void doit(void *arg)
{
    char buffer[BUFSIZ];
    ssize_t size;
    while((size=read(STDIN_FILENO,buffer,sizeof(buffer)))>0){
        buffer[size-1]='\0';
        write(sockfd,buffer,size);
    }
    shutdown(sockfd,SHUT_WR);
}
void cli_do(int sockfd)
{
    char buffer[BUFSIZ];
    pthread_t th;
    ssize_t size;
    
    pthread_create(&th,NULL,doit,NULL);
    while((size=read(sockfd,buffer,sizeof(buffer)))>0){
        buffer[size-1]='\0';
        write(STDOUT_FILENO,buffer,size);
    }
}
int main(int argc,char *argv[])
{
    if(argc<3){
        printf("usage:%s <ip><port>",argv[0]);
        exit(1);
    }
    /*create socket*/
    sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd<0){
        perror("socket create fail\n");
    }
    struct sockaddr_in serveraddr;
    serveraddr.sin_family=AF_INET;
    serveraddr.sin_port=htons(atoi(argv[2]));
    inet_pton(AF_INET,argv[1],&serveraddr.sin_addr.s_addr);
    if(connect(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr))<0){
        perror("server connect fail\n");
        exit(1);
    }
    cli_do(sockfd);
    close(sockfd);
    return 0;
}

 

转载于:https://www.cnblogs.com/peixiguang/p/6058901.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值