簡體   English   中英

C套接字編程,服務器發送緩沖區似乎不被清除

[英]C socket programming, server send buffer seems not to be cleared

我是socket編程的新手,我遇到了麻煩。 我想實現一個服務器,根據某個客戶端請求回答。 在我的情況下,GET,HEAD或其他錯誤。 考慮以下代碼

如果我在調用send()之前打印答案(參見下面的服務器端代碼),則消息是正確的。 但是,假設我發送給客戶的是

  1. 得到
  2. 得到
  3. 測試
  4. 得到

,從客戶端打印的答案是

You want GET
You want HEAD
You want GETD
HTTP/1.1 400 Bad Request
You want GET Bad Request

因此,似乎從服務器發送的消息有點“覆蓋”,但這怎么可以避免呢? 是否可以“清除服務器緩沖區”,如果這是問題呢?

這是完整的服務器端代碼

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#define BUFSIZE         1024
#define MAXPENDING      100

int main(){

    char get[] = "GET";
    char head[] = "HEAD";
    int serverSocket = socket(PF_INET, SOCK_STREAM, 0);

    struct sockaddr_in serverAddress;
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_port = htons(8080);
    serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
    memset(&serverAddress.sin_zero, '\0', 8);

    bind(serverSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress));

    listen(serverSocket, MAXPENDING);

    for(;;){
        struct sockaddr_in clientAddress;
        int clientAddressLength = sizeof(clientAddress);
        int clientSocket;

        clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddress, &clientAddressLength);

        char buf[BUFSIZE];
        int bytesRec;

        bytesRec = recv(clientSocket, buf, BUFSIZE, 0);
        while(bytesRec > 0){

            char *result;
            result = strtok(buf, " ");

            printf("result %s\n", result);

            if(strcmp(&buf, &get) == 0){
                char answer[] = "You want GET";
                send(clientSocket, answer, strlen(answer), 0);
            }else{
                if(strcmp(&buf, &head) == 0){
                    char answer[] = "You want HEAD";
                    send(clientSocket, answer, strlen(answer), 0);
                }else{
                    char answer[] = "HTTP/1.1 400 Bad Request";
                    send(clientSocket, answer, strlen(answer), 0); 
                }
            }

            bytesRec = recv(clientSocket, buf, BUFSIZE, 0);
        }

    return 0;
}

和客戶端

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

int main(){

    int clientSocket = socket(PF_INET, SOCK_STREAM, 0);

    struct sockaddr_in clientAddress;
    clientAddress.sin_family = AF_INET;
    clientAddress.sin_port = 0;
    clientAddress.sin_addr.s_addr = htonl(INADDR_ANY);
    memset(&clientAddress.sin_zero, '\0', 8/*sizeof(clientAddress.sin_zero)*/);

    bind(clientSocket, (struct sockaddr*)&clientAddress, sizeof(clientAddress));

    struct sockaddr_in serverAddress;
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_port = htons(8080);
    serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
    memset(&serverAddress.sin_zero, '\0', 8);

    if(connect(clientSocket, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == -1){
        printf("error in connecting!\n");
        return 0;
    }

    char* serverReply[1024];

    for(;;){
        char request[100];
        printf("Enter your request: ");
        scanf("%s", &request);
        send(clientSocket, request, strlen(msg), 0);
        if(recv(clientSocket, serverReply, strlen(serverReply), 0) < 0){
            printf("failure in receiving from server!\n");
        }else{
            printf("%s\n", serverReply);
        }
    }

    close(clientSocket);

    return 0;
}
send(clientSocket, request, strlen(msg), 0);

這僅發送字符串字符,不包括終止NULL。 接收緩沖區不會終止服務器端收到的字符串。

這就是您仍然可以看到上一條消息中的“D”字符的原因。

You want GETD <-- 'D' is from the previous 'HEAD'

在服務器上終止接收到的字符串,

buf[bytesRec] = '\0';

編輯:正如@Zan所指出的,不要這樣做:

或從客戶端發送NULL終止符。

 send(clientSocket, request, strlen(msg) + 1, 0); 

你的strcmp()如果錯了

(1)而不是buf,您需要將result與我可以從您的問題中了解的result進行比較,例如:(您在注釋中說,結果打印為GET)

if(strcmp(result, get) == 0){

(2) @phihag回答應該是

if(strcmp(buf, get) == 0){
          ^   ^remove &

你在每個strcmp()上都有類似的錯誤,因為bufgethead都是包機數組。

(3) recv()不會終止讀取緩沖區,因此在使用它之前最好添加null( \\0 )( 因為我可以注意到您使用buff作為字符串

喜歡:

bytesRec = recv(clientSocket, buf, BUFSIZE, 0);
buf[bytesRec] = '\0'

感染你應該只讀取BUFSIZE-1個字節,一個用於null '\\0'符號,如:

ytesRec = recv(clientSocket, buf, BUFSIZE-1, 0);
buf[bytesRec] = '\0' 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM