源码

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <unistd.h>//close
#include <sys/socket.h>//socket
#include <arpa/inet.h>//inet_pton
#include <netinet/in.h>// sockaddr_in
int main()
{
    //1、创建套接字
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd<0)
    {
        perror("socket");
        return -1;
    }
    //2、绑定指定地址
    struct sockaddr_in serveraddr;
    serveraddr.sin_family=AF_INET;
    serveraddr.sin_port=htons(8005);
    serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
    bind(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));

    //3、套接字从主动变被动,并且创建队列保存连接客户端(监听)
    listen(sockfd,10);

    struct sockaddr_in cliaddr;
    socklen_t clilen=sizeof(cliaddr);

    //5、循环接受消息,并自动回复ok
    char buf[1024]="";
    int len;
    int fd_new;
    pid_t pid;
    while(1){

        //4、多次提取
        fd_new=accept(sockfd,(struct sockaddr *)&cliaddr,&clilen);
        //如果accept函数阻塞解除,说明提取到了一个客户端,我们需要一边跟这个客户端循环收发消息,一边继续提取
        pid=fork();
        if(pid<0)
        {
            close(fd_new);
            close(sockfd);
            return -1;
        }
        else if(pid==0){//任务1:循环收发消息
            close(sockfd);
            while(1){
            //接受消息
            len=recv(fd_new,buf,sizeof(buf),0);//如果客户端断开,会给服务器发送0长度数据包
            printf("recv:%s\n",buf);
            //回复ok
            send(fd_new,"ok",strlen("ok"),0);
            if(len==0)//如果收到了0长度数据包,说明客户端断开,服务器也跟着结束
                break;    
            }
        }
        else{//任务2:继续提取
            close(fd_new);
        }

    }
    //6、关闭套接字
    close(fd_new);
    close(sockfd);
    return 0;
}

编译时,加上线程库

gcc a.c -lpthread