使用线程的TCP回射服务端和客户端运行时错误

服务端serv.c:

 #include "unp.h"
#include <pthread.h>

void str_echo(int sockfd)
{
    char buf[MAXLINE];
    int n;
    while(( n = read(sockfd,buf,sizeof(buf)))>=0)
    {   
        if (n ==0)
        {
            printf("client EOF,its use shutdown sockfd\n");
            exit(0);
        }
        write(sockfd,buf,sizeof(buf));
    }
    if (n < 0)
    {
        perror("read data from sockfd error");
        exit(1);
    }
}
static void *doit(void *arg)
{
    pthread_detach(pthread_self());
    str_echo((int) arg);
    close((int)arg);
    return 0;
}

int main(int argc, char const *argv[])
{
    int listenfd,connfd;
    int on = 1;
    pthread_t tid;
    struct sockaddr_in seraddr;
    struct sockaddr_in cliaddr;
    socklen_t len;

    bzero(&seraddr,sizeof(seraddr));
    seraddr.sin_family = AF_INET;
    seraddr.sin_port = htons(SERV_PORT);
    seraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    len = sizeof(seraddr);

    listenfd = socket(AF_INET,SOCK_STREAM,0);
    if (listenfd < 0)
    {
        perror("creat listenfd error");
        exit(1);
    }
    setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
    if (bind(listenfd,(SA*)&seraddr,len) <0)
    {
        perror("bind error");
        exit(1);
    }
    if (listen(listenfd,10) < 0)
    {
        perror("listen error");
        exit(1);
    }
    for (; ;)
    {
        connfd = accept(listenfd,NULL,NULL);
        if (pthread_create(&tid,NULL,doit,(void *)&connfd) != 0)
        {
            perror("pthread_create error");
            exit(1);
        }
    }
    return 0;
}

客户端client.c:

 #include "unp.h"
#include <pthread.h>

void *copyto(void *arg);

static int sockfd;
static FILE *fp;

void str_cli(FILE *fp_arg,int sockfd_arg)
{
    char recvbuf[MAXLINE];
    int readn;
    pthread_t tid;

    sockfd = sockfd_arg;
    fp = fp_arg;
    if (pthread_create(&tid,NULL,copyto,NULL) != 0)
    {
        perror("pthread_create error");
        exit(1);
    }

    while((readn = read(sockfd,recvbuf,sizeof(recvbuf))) >0)
    {
        recvbuf[readn+1] =0;
        fputs(recvbuf,stdout);
    }
    if (readn ==0)
    {
        printf("server terminate, read 0\n");
    }
}

void *copyto(void *arg)
{
    char sendbuf[MAXLINE];
    int writen;
    while(fgets(sendbuf,sizeof(sendbuf),stdin) != NULL)
    {
        writen = write(sockfd,sendbuf,sizeof(sendbuf));
        if (writen < 0)
        {
            perror("write sockfd error");
        }
    }
    // use shotdown,when fgets return null
    shutdown(sockfd,SHUT_WR);
    return NULL;
}

int main(int argc, char const *argv[])
{
    struct sockaddr_in servaddr;

    if (argc != 2)
    {
        printf("Usage exe serverip\n");
        exit(1);
    }
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERV_PORT);
    inet_pton(AF_INET,argv[1],&servaddr.sin_addr.s_addr);

    sockfd = socket(AF_INET,SOCK_STREAM,0);
    if (sockfd < 0)
    {
        perror("creat sockfd error");
        exit(1);
    }
    if (connect(sockfd,(SA*)&servaddr,sizeof(servaddr)) < 0)
    {
        perror("connect error");
        exit(1);
    }
    str_cli(stdin,sockfd);
    return 0;
}

编译均在正确通过,但是服务端启动后,在启动客户端,服务端返回:read data from sockfd error: Bad file descriptor
求大神帮忙解决

调试下,看看是不是连接被你关闭了

还有这个http://zhanyonhu.blog.163.com/blog/static/16186044201061214436331/