交流电插座编程,服务器发送缓冲区似乎并没有被清除 [英] C socket programming, server send buffer seems not to be cleared

查看:190
本文介绍了交流电插座编程,服务器发送缓冲区似乎并没有被清除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很新的Socket编程和我有它的烦恼。我想要实现依赖于一定的客户端请求应答服务器。就我而言,无论是GET,HEAD,否则错误。考虑以下code

如果我打电话发送之前打印的答案()(见服务器端code以下),该消息是正确的。但是,让我们从客户端我送说。


  1. GET

  2. HEAD

  3. GET

  4. 测试

  5. GET

,从客户端印制答案是

 你要GET
你想HEAD
你想GETD
HTTP / 1.1 400错误的请求
你想GET请求无效

因此​​,它似乎是从服务器发送的消息是怎么样的覆盖,这是怎么回事可以避免的?是否有可能为清除服务器缓冲区如果是这样的问题呢?

下面是完整的服务器端code

 的#include<&stdio.h中GT;
#包括LT&;&string.h中GT;
#包括LT&; SYS / types.h中>
#包括LT&; SYS / socket.h中>
#包括LT&; netinet / in.h中>
#包括LT&; ARPA / inet.h>
#包括LT&;&netdb.h中GT;的#define BUFSIZE 1024
#定义MAXPENDING 100诠释主(){    CHAR得到[] =GET;
    焦头[] =HEAD;
    INT的ServerSocket =插座(PF_INET,SOCK_STREAM,0);    结构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);    绑定(ServerSocket类(结构sockaddr *)及serverAddress,sizeof的(serverAddress));    听(ServerSocket的,MAXPENDING);    对于(;;){
        结构SOCKADDR_IN clientAddress;
        INT clientAddressLength = sizeof的(clientAddress);
        INT ClientSocket的;        ClientSocket的=接受(ServerSocket类(结构sockaddr *)及clientAddress,&安培; clientAddressLength);        烧焦的buf [BUFSIZE];
        INT bytesRec;        bytesRec =的recv(ClientSocket的,BUF,BUFSIZE,0);
        而(bytesRec大于0){            字符*的结果;
            结果=的strtok(BUF,);            的printf(结果%S \\ n,结果);            如果(STRCMP(安培; BUF,&安培;获得)== 0){
                CHAR答案[] =你要GET;
                发送(ClientSocket的,答案,strlen的(答案),0);
            }其他{
                如果(STRCMP(安培; BUF,&安培;头)== 0){
                    CHAR答案[] =你要HEAD;
                    发送(ClientSocket的,答案,strlen的(答案),0);
                }其他{
                    CHAR答案[] =HTTP / 1.1 400错误的请求;
                    发送(ClientSocket的,答案,strlen的(答案),0);
                }
            }            bytesRec =的recv(ClientSocket的,BUF,BUFSIZE,0);
        }    返回0;
}

和客户端

 的#include<&stdio.h中GT;
#包括LT&;&string.h中GT;
#包括LT&; SYS / types.h中>
#包括LT&; SYS / socket.h中>
#包括LT&; netinet / in.h中>
#包括LT&; ARPA / inet.h>
#包括LT&;&netdb.h中GT;诠释主(){    INT ClientSocket的=插座(PF_INET,SOCK_STREAM,0);    结构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)* /);    绑定(ClientSocket的,(结构sockaddr *)及clientAddress,sizeof的(clientAddress));    结构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);    如果(连接(ClientSocket的,(结构sockaddr *)及serverAddress,sizeof的(serverAddress))== -1){
        的printf(在连接错误。\\ n!);
        返回0;
    }    字符* serverReply [1024];    对于(;;){
        焦炭的要求[100];
        的printf(请输入您的请求:);
        scanf函数(%S,&安培;要求);
        发送(ClientSocket的,请求的strlen(MSG),0);
        如果(的recv(ClientSocket的,serverReply,strlen的(serverReply),0)℃,){
            的printf(失败,从服务器接收\\ n!);
        }其他{
            的printf(%S \\ n,serverReply);
        }
    }    关闭(ClientSocket的);    返回0;
}


解决方案

 发(ClientSocket的,请求的strlen(MSG),0);

此仅发送字符串的字符,不包括终止NULL。接收缓冲区不会终止在服务器端接收到的字符串。

这就是为什么你仍然看到从previous消息D字。

 你想GETD<  - 'D'是从$​​ P $ pviousHEAD

要么终止服务器上接收到的字符串,

  BUF [bytesRec] ='\\ 0';

或从客户端发送空终止符。

 发(ClientSocket的,请求的strlen(MSG)+ 1,0);

I am very new to socket programming and I have troubles with it. I want to implement a server that answers depending on a certain client request. In my case, either GET, HEAD or an error else. Consider following code

If I print the answer before calling send() (see server side code below), the message is correct. But let's say from the client I send

  1. GET
  2. HEAD
  3. GET
  4. test
  5. GET

, the answer printed from the client side is

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

So it seems like that the message sent from the server is kind of 'overwritten', but how is this avoidable? Is it possible to 'clear the server buffer' if that is the problem at all?

Here is the full server side code

#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;
}

and the client side

#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);

This sends only the string characters and does not include the terminating NULL. The receive buffer does not terminate the received string on the server side.

This is why you are still seeing the 'D' character from the previous message.

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

Either terminate the received string on the server,

buf[bytesRec] = '\0';

or send the NULL terminator from the client.

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

这篇关于交流电插座编程,服务器发送缓冲区似乎并没有被清除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆