C套接字间歇性地重置连接并且没有收到来自python请求的完整请求

我有一个 python 程序,我想通过 http 与 C 程序通信。我在 python 中使用请求将一些 json 数据发送到 C 中的套接字。

有时,python 会吐出“由对等方重置连接”错误,我无法弄清楚。当我收到这个错误时,除了请求的内容之外的所有内容都由 C 程序发送和接收。在我的应用程序中,我还从一个用 Go 编写的客户端发出请求。对于那个客户端,我永远不会收到这些错误,这就是为什么我认为我在请求库中缺少一些配置或简单的解决方案。为什么会发生这种情况,什么可以解决我的问题?

这是一个简单的例子;套接字的东西显然是我不太熟悉的:

C服务器:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/socket.h>

#include <netinet/in.h>


#define RECV_BUF_SIZE 1024


int main(void)

{

    struct sockaddr_in serv_addr, cli_addr;

    serv_addr.sin_family = AF_INET;

    serv_addr.sin_addr.s_addr = INADDR_ANY;

    serv_addr.sin_port = htons(8080);


    int option = 1;

    int socketfd = socket(AF_INET, SOCK_STREAM, 0);

    setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));

    if (socketfd < 0)

    {

        perror("failed to start socket");

        exit(1);

    }


    if (bind(socketfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) < 0)

    {

        perror("failed to bind");

        exit(1);

    }


    if (listen(socketfd, 1000) != 0)

    {

        perror("listen error");

        exit(1);

    }


    char buf[RECV_BUF_SIZE];


    while (1)

    {

        int addrlen = sizeof(cli_addr);

        int clientfd = accept(socketfd, (struct sockaddr*) &cli_addr, &addrlen);

        if (clientfd < 0)

        {

            perror("accept error");

        }

        else

        {

            int n_recv = recv(clientfd, buf, RECV_BUF_SIZE, 0);


            // print everything, character by character.

            char* tmp_buf = buf;

            while (n_recv--) printf("%c", *tmp_buf++);

            printf("\n\n****************************\n\n");


            FILE* res = fdopen(clientfd, "w");

            fprintf(res, "HTTP/1.1 200 OK\r\n\r\n");

            fclose(res);

            shutdown(clientfd, SHUT_RDWR);

            close(clientfd);

        }

    }

}

Python 请求脚本:


import requests


json_data = {

    "hello": "thanks"

}


requests.post("http://localhost:8080", json=json_data)

谢谢!


红糖糍粑
浏览 90回答 1
1回答

喵喵时光机

关于服务器与客户端的通信,有几个小问题,比如不正确的变量类型和缺乏错误检查。我在我的评论前面加上了>>'条件编译'来展示我如何用建议的改进替换了 OPs 代码的某些部分。警告:由于服务器不知道从客户端接收的预期字节数,因此答案不包括循环,试图检索客户端预期的所有字节char buf[ RECV_BUF_SIZE +1 ];&nbsp; // >> +1 for string terminatorwhile (1){&nbsp; &nbsp; // >> the third parameter is a 'socklen_t', not an 'int'&nbsp; &nbsp; socklen_t addrlen = sizeof(cli_addr);&nbsp; &nbsp; int clientfd =&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; accept(socketfd, (struct sockaddr*) &cli_addr, &addrlen);&nbsp; &nbsp; if (clientfd < 0)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; perror("accept error");&nbsp; &nbsp; }&nbsp; &nbsp; else&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; // >>recv() returns a `ssize_t`, not an `int`&nbsp; &nbsp; &nbsp; &nbsp; ssize_t n_recv = recv(clientfd, buf, RECV_BUF_SIZE, 0);&nbsp; &nbsp; &nbsp; &nbsp; #if 0&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // >>this takes WAY too long, so the connection&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // >>could timeout&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // print everything, character by character.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; char* tmp_buf = buf;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (n_recv--) printf("%c", *tmp_buf++);&nbsp; &nbsp; &nbsp; &nbsp; #else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if( n_recv < 0 )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; // then an error occurred&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; perror( "recv failed" );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; write( clientfd,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"receive error",&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sizeof( "receive error" ) );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; close( clientfd );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if( n_recv == 0 )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; // then client closed connection&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf( "%s\n",&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "client closed connection" );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; close( clientfd );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { // some data received from client&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buf[ n_recv ] = '\0';&nbsp; // terminate string&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf( "%s\n", buf );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; #endif&nbsp; &nbsp; &nbsp; &nbsp; printf("\n\n****************************\n\n");&nbsp; &nbsp; &nbsp; &nbsp; #if 0&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FILE* res = fdopen(clientfd, "w");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fprintf(res, "HTTP/1.1 200 OK\r\n\r\n");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fclose(res);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; shutdown(clientfd, SHUT_RDWR);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; close(clientfd);&nbsp; &nbsp; &nbsp; &nbsp; #else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ssize_t writeBytes;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if( (writeBytes =&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;write( clientfd,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "HTTP/1.1 200 OK\r\n\r\n",&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; strlen( "HTTP/1.1 200 OK\r\n\r\n" ) ) )&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; != strlen( "HTTP/1.1 200 OK\r\n\r\n" ) )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { // then incomplete write&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf( "%s\n",&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "write didn't write all bytes to client" );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; close( clientfd );&nbsp; &nbsp; &nbsp; &nbsp; #endif&nbsp; &nbsp; }}分享编辑跟随关于服务器与客户端的通信,有几个小问题,比如不正确的变量类型和缺乏错误检查。我在我的评论前面加上了>>'条件编译'来展示我如何用建议的改进替换了 OPs 代码的某些部分。警告:由于服务器不知道从客户端接收的预期字节数,因此答案不包括循环,试图检索客户端预期的所有字节char buf[ RECV_BUF_SIZE +1 ];&nbsp; // >> +1 for string terminatorwhile (1){&nbsp; &nbsp; // >> the third parameter is a 'socklen_t', not an 'int'&nbsp; &nbsp; socklen_t addrlen = sizeof(cli_addr);&nbsp; &nbsp; int clientfd =&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; accept(socketfd, (struct sockaddr*) &cli_addr, &addrlen);&nbsp; &nbsp; if (clientfd < 0)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; perror("accept error");&nbsp; &nbsp; }&nbsp; &nbsp; else&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; // >>recv() returns a `ssize_t`, not an `int`&nbsp; &nbsp; &nbsp; &nbsp; ssize_t n_recv = recv(clientfd, buf, RECV_BUF_SIZE, 0);&nbsp; &nbsp; &nbsp; &nbsp; #if 0&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // >>this takes WAY too long, so the connection&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // >>could timeout&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // print everything, character by character.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; char* tmp_buf = buf;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (n_recv--) printf("%c", *tmp_buf++);&nbsp; &nbsp; &nbsp; &nbsp; #else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if( n_recv < 0 )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; // then an error occurred&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; perror( "recv failed" );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; write( clientfd,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"receive error",&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sizeof( "receive error" ) );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; close( clientfd );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if( n_recv == 0 )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; // then client closed connection&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf( "%s\n",&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "client closed connection" );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; close( clientfd );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { // some data received from client&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buf[ n_recv ] = '\0';&nbsp; // terminate string&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf( "%s\n", buf );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; #endif&nbsp; &nbsp; &nbsp; &nbsp; printf("\n\n****************************\n\n");&nbsp; &nbsp; &nbsp; &nbsp; #if 0&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FILE* res = fdopen(clientfd, "w");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fprintf(res, "HTTP/1.1 200 OK\r\n\r\n");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fclose(res);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; shutdown(clientfd, SHUT_RDWR);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; close(clientfd);&nbsp; &nbsp; &nbsp; &nbsp; #else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ssize_t writeBytes;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if( (writeBytes =&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;write( clientfd,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "HTTP/1.1 200 OK\r\n\r\n",&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; strlen( "HTTP/1.1 200 OK\r\n\r\n" ) ) )&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; != strlen( "HTTP/1.1 200 OK\r\n\r\n" ) )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { // then incomplete write&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf( "%s\n",&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "write didn't write all bytes to client" );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; close( clientfd );&nbsp; &nbsp; &nbsp; &nbsp; #endif&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python