如果我想逐个从客户端到服务器写多个请求,我该怎么办?

时间:2015-12-06 04:35:59

标签: c sockets client-server

例如,文件中有多个请求,我读取它们然后使用write函数逐行发送到服务器。但是,服务器只有一个响应,我无法读取服务器的整个请求。有谁可以帮我解决这个问题。非常感谢你!

有服务器代码:

    <pre> <code>
    int main(int argc, char *argv[]){
    int sockfd, newsockfd, n;
    unsigned int clientLen;
    char bufferSK[256];
    struct sockaddr_in serv_addr,cli_addr;
    FILE *fp = NULL;

    //create an endpoint for bind, listen and accept.
    sockfd = socket(AF_INET,SOCK_STREAM,0);
    if (sockfd < 0) {
        printf("Failed to create socket for server!\n");
    }
    bzero((char *)&serv_addr, sizeof(serv_addr));

    //set the address of server.
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(port_number);

    //bind the port with server address
    if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        printf("Error on bind!\n");
    }
    listen(sockfd,port_number);
    printf("\nI am listening for connection\n");
    clientLen = sizeof(cli_addr);

    //using accept function to accept the connection from client
    newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clientLen);
    if (newsockfd < 0) {
        printf("Error on accept!\n");
    }
    printf("\nI have accepted your connection\n");
    bzero(bufferSK,256);
    n = read (newsockfd, bufferSK,255);
    if (n < 0) {
        printf("Error reading message from socket\n");
    }

    printf("\nThe message from client is: %s",bufferSK);
    n = write(newsockfd, "SERVER: I got your message!\n", 27);
    if (n < 0) {
        printf("Error writing to socket\n");
    }
    close(newsockfd);
    close(sockfd);
    return 0;
}

有客户端代码:

<pre> <code>

    FILE *fp_queue;

    int main(int argc, char *argv[]){
    int sockfd, server_port_number, n, connectRes;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    char buffer[256];

    //Three parameters must be provided.
    if(argc != 4){
        fprintf(stderr, "Usage: %s server_host_name server_port_number file_path\n",argv[0]);
        exit(0);
    }
    server_port_number = atoi(argv[2]);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    //create socket for client.
    if (sockfd < 0) {
        printf("Failed to create socket for client\n");
        exit(0);
    }

    server = gethostbyname(argv[1]);
    if (server == NULL) {
        printf("Oops! There is no such host!\n");
        exit(0);
    }

    //set the attributes of server as zeros.
    bzero((char *)&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    //copy the server address from serv_addr.sin_addr.s_addr to server->h_adddr.
    bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);

    serv_addr.sin_port = htons(server_port_number);
    connectRes = connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
    if (connectRes < 0) {
        printf("Error connection\n");
        exit(0);
    }
    printf("connect successfully\n");
    fp_queue = fopen(argv[3], "r");
    if (fp_queue == NULL) {
        printf("Failed open client file %s\n", argv[3]);
        exit(1);
    }

    bzero(buffer, 256);
    while ((fgets(buffer,sizeof(buffer),fp_queue)) != NULL) {
        buffer[strlen(buffer) - 1] = '\0';
        printf("buffer is %s\n", buffer);
        n = write(sockfd, buffer, strlen(buffer));
        if (n < 0) {
            printf("Error write to socket\n");
        }
        bzero(cliBuffer, 256);
        n = read(sockfd, buffer, 256);
        if (n <0) {
            printf("Error read from socket\n");
        }
        printf("%s\n", buffer);
    }
    close(sockfd);
    return 0;
}

1 个答案:

答案 0 :(得分:1)

代码中至少存在2个设计问题。

服务器代码接收一个请求,发送响应然后服务器终止。如果要通过一个连接处理更多请求,则服务器代码必须包含类似于客户端的循环。服务器代码应包含类似

的内容
while ((n = read (newsockfd, bufferSK, 255) > 0) {
    printf("\nThe message from client is: %s",bufferSK);
    n = write(newsockfd, "SERVER: I got your message!\n", 27);
    if (n < 0) {
        printf("Error writing to socket\n");
        break;
    }
}
close(newsockfd);

下一个问题是TCP是面向流的协议,您的代码不会考虑这一点。流方向意味着协议不保持消息边界。当发送方呼叫write("a"); write("b")时,接收方可以在两个单独的读取中获取字符,或者在一次读取中可以接收2个字符。为了克服这个问题,对等体必须定义一些协议如何确定消息边界。通常客户端在消息开头发送消息长度,或者控制字符用作消息边界或消息具有固定长度。