2022-4-16 Escritura centralizada del servidor

código del lado del servidor

#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<netdb.h>
#include<stdio.h>
#include<unistd.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include <sys/uio.h>
#define BUFFER_SIZE 1024
static const char*status_line[2] = {
    
    "200 OK","500 Internal Server Error"};
int main(void){
    
    

    //1.要集中写的数据
    const char*file_name = "daytime.c";
    //2.绑定服务端的监听地址
    struct sockaddr_in address;
    bzero(&address,sizeof(address));
    address.sin_family = AF_INET;
  //inet_pton(AF_INET,"192.168.131.137",&address.sin_addr);
  //inet_pton(AF_INET,"localhost",&address.sin_addr);
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(9999);
    int sock = socket(AF_INET,SOCK_STREAM,0);
    if(sock == -1){
    
    
        perror("socket");
        return 1;
    }
    int ret = bind(sock,(struct sockaddr*)& address,sizeof(address));
    if(ret == -1){
    
    
        perror("bind");
        return 1;
    }
    //3.监听
    ret = listen(sock,5);
    if(ret == -1){
    
    
        perror("listen");
        return 1;
    }
    //4.接受客户端连接
    struct sockaddr_in client;
    socklen_t len = sizeof(client);
    int connfd = accept(sock,(struct sockaddr*)&client,&len);
    if(connfd == -1){
    
    
        perror("accept");
        return 1;
    }else {
    
    
        //5.输出客户端信息
        char clientIP[16];
        inet_ntop(AF_INET,&client.sin_addr.s_addr,clientIP,sizeof(clientIP));
        unsigned short int port = ntohs(client.sin_port);
        printf("client ip is %s,port is %d.\n",clientIP,port);

        char header_buffer[BUFFER_SIZE];
        memset(header_buffer,'\0',BUFFER_SIZE);

        char*file_buf;
        struct stat file_stat;
        bool valid = true;
        int len2 = 0;
        //获取文件的信息
        if(stat(file_name,&file_stat) == -1){
    
    
            valid = false;
        }else{
    
    
            //检查是否是目录
            if(S_ISDIR(file_stat.st_mode)){
    
    
                valid = false;
            }else if(file_stat.st_mode & S_IROTH){
    
    
                //判断其他用户是否具有可读权限
                int fd = open(file_name,O_RDONLY);
                file_buf = new char[file_stat.st_size+1];
                memset(file_buf,'\0',file_stat.st_size+1);
                //将文件读入当前的缓冲区当中
                if(read(fd,file_buf,file_stat.st_size) == -1){
    
    
                    valid = false;
                }
            }else{
    
    
                valid = false;
            }
        }
        if(valid){
    
    
            //写入版本号和状态码
            ret = snprintf(header_buffer,BUFFER_SIZE-1,"HTTP/1.1 %s\r\n",status_line[0]);
            len2 += ret;
            //写入文件长度
            ret = snprintf(header_buffer+len2,BUFFER_SIZE-1-len,"Content-Length:%ld\r\n",file_stat.st_size);
            len2 += ret;
            //换行符
            ret = snprintf(header_buffer+len,BUFFER_SIZE-1-len2,"%s","\r\n");
            //iovec结构体用来描述有几块内存和每块内存有多大,用于集中读和集中写
            struct iovec iv[2];
            iv[0].iov_base = header_buffer;
            iv[0].iov_len = strlen(header_buffer);
            iv[1].iov_base = file_buf;
            iv[1].iov_len = file_stat.st_size;
            ret = writev(connfd,iv,2);
            //需要加入头文件#incldue<sys/uio.h>

        }else {
    
    
            //如果是无效的文件,则通知错误信息
            ret = snprintf(header_buffer,BUFFER_SIZE-1,"%s%s\r\n","HTTP/1.1",status_line[1]);
            len2 += ret;
            ret = snprintf(header_buffer+len,BUFFER_SIZE-1-len,"%s","\r\n");
            send(connfd,header_buffer,strlen(header_buffer),0);
        }
        close(connfd);
        delete[] file_buf;
    }
    close(sock);
    return 0;
}

codigo del cliente

//tcp 通信客户端
#include<stdio.h>
#include<arpa/inet.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>

int main(void){
    
    
    //1.创建套接字
    int fd = socket(AF_INET,SOCK_STREAM,0);
    if(fd == -1){
    
    
        perror("socket");
        exit(0);
    }

    //2.连接服务器端
    struct sockaddr_in serveraddr;
    serveraddr.sin_family = AF_INET;
    inet_pton(AF_INET,"192.168.131.138",&serveraddr.sin_addr.s_addr);
    serveraddr.sin_port = htons(9999);
    int ret = connect(fd,(struct sockaddr*)&serveraddr,sizeof(serveraddr));
    if(ret == -1){
    
    
        perror("connect");
        exit(0);
    }

    //3.通信
    // char *data = "hello , i am client.";
    // write(fd,data,strlen(data));

    char recvBuf[1024] = {
    
    0}; 
    while(read(fd,recvBuf,sizeof(recvBuf)) > 0){
    
    
        printf("%s\n",recvBuf);
    }
    // int len2 = read(fd,recvBuf,sizeof(recvBuf));
    // if (len2 == -1)
    // {
    
    
    //     perror("read");
    //     exit(-1);
    // }
    // else if(len2 > 0){
    
    
    //     printf("recv client data : %s\n",recvBuf);

    // }else if(len2 == 0){
    
    
    //     //表示服务端断开连接
    //     printf("server closed.\n");
    // }
    close(fd);

    return 0;
}

Salida del servidor Salida del
inserte la descripción de la imagen aquí
cliente
Algunos símbolos son extraños
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/weixin_51187533/article/details/124210927
Recomendado
Clasificación