【问题标题】:Socket Programming HTTP, socket gets closed on its own and recv() return 0 when delayedSocket 编程 HTTP,socket 自行关闭,recv() 延迟时返回 0
【发布时间】:2020-09-28 12:03:21
【问题描述】:

我是套接字编程的新手,我从 Lewis Van Winkle - Hands-On Network Programming with C 那里得到了 TCP 编程的介绍。这是我的第一个问题,如果有的话,请指出。 对于来自注册或登录页面的 POST REQUEST,套接字会自行关闭。
有时甚至对于 GET 请求,经过一些延迟后,recv() 函数返回 0 并且不发送任何数据;
一点帮助或朝着正确的方向轻推会有所帮助
我的代码如下:-

#if defined(_WIN32)
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
#endif
#include <winsock2.h>
#include <ws2tcpip.h>
#include<io.h>
#include <process.h>
#pragma comment(lib, "ws2_32.lib")
#else
#include <sys/types.h>
#include <sys/socket.h>
#include<sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#endif
#if defined(_WIN32)
#define ISVALIDSOCKET(s) ((s) != INVALID_SOCKET)
#define CLOSESOCKET(s) closesocket(s)
#define GETSOCKETERRNO() (WSAGetLastError())
#else
#define ISVALIDSOCKET(s) ((s) >= 0)
#define CLOSESOCKET(s) close(s)
#define SOCKET int
#define GETSOCKETERRNO() (errno)
#endif


#if defined(_WIN32) 
#else 
#define mkdir(s) mkdir(s,0666)
#endif



#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int ReadFrom(char uri[], char buffer[],SOCKET c1){

        sprintf(buffer, "HTTP/1.1 200 OK\r\n");
    send(c1, buffer, strlen(buffer), 0);
    sprintf(buffer, "Connection: close \r\n");
    send(c1, buffer, strlen(buffer), 0);
    sprintf(buffer, "Content-Type: text/html\r\n");
    send(c1, buffer, strlen(buffer), 0);
printf("\ntillhere23\n");
    sprintf(buffer, "\r\n");
    printf("\ntillhere23\n");
    send(c1, buffer, strlen(buffer), 0);
    char filename[30]="./public/";
    strcat(filename,uri);
    printf("\ntillhere23\n");
    strcat(filename,".html");
    FILE *fp=fopen(filename,"rb");
    printf("\ntillhere23 %s  %d %c \n",filename,fp,fp);
    fseek(fp, 0L, SEEK_END);
    printf("\ntillhere23 %s\n",filename);
    size_t cl = ftell(fp);
    printf("\ntillhere23 %s\n",filename);
    rewind(fp);
    printf("\ntillhere23 %s\n",filename);
    printf("%s helo :: \n",buffer);
    int r = fread(buffer, 1, 1024, fp);
    while (r) {
        send(c1, buffer, r, 0);
        r = fread(buffer, 1, 1024, fp);
    }

    fclose(fp);
}
int main(){
    #if defined(_WIN32)
    WSADATA d;
    if (WSAStartup(MAKEWORD(2, 2), &d)) {
        fprintf(stderr, "Failed to initialize.\n");
        return 1;
    }
#endif


    printf("Configuring local address...\n");
    struct addrinfo hints;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;

    struct addrinfo *bind_address;
    getaddrinfo("127.0.0.1","8080", &hints, &bind_address);

    printf("Creating socket...\n");
    SOCKET socket_listen;
    socket_listen = socket(bind_address->ai_family,
            bind_address->ai_socktype, bind_address->ai_protocol);

    if (!ISVALIDSOCKET(socket_listen)) {
        fprintf(stderr, "socket() failed. (%d)\n", GETSOCKETERRNO());
        exit(1);
    }

    printf("Binding socket to local address...\n");
    if (bind(socket_listen,
                bind_address->ai_addr, bind_address->ai_addrlen)) {
        fprintf(stderr, "bind() failed. (%d)\n", GETSOCKETERRNO());
        exit(1);
    }

    freeaddrinfo(bind_address);
    SOCKET Server=socket_listen;
    SOCKET c1=-1;
    struct sockaddr_storage client_address;
 socklen_t client_len = sizeof(client_address);

    while(1){
        printf("Listening...\n");
    if (listen(socket_listen, 10) < 0) {
        fprintf(stderr, "listen() failed. (%d)\n", GETSOCKETERRNO());
        exit(1);
    }
        c1 = accept(socket_listen,
 (struct sockaddr*) &client_address,
    &client_len);
        printf("CAME BACK %d\n",c1);
    printf("CAME BACK2 :: %d\n",c1);
    char buffer[1024];
    char req[1024];
    printf("receiving starts now::\n");
        printf("STATUS OF RECV: %d",recv(c1,req,1024,0));
        printf("\nRCV:\n%s\n",req);
        /*for(int i=0;i<strlen(req);i++){
            printf("\ni::%d ,char: %c, num:%d\n",i,req[i],req[i]);

        }


        printf("\n ABOVE CONTAINS ALLREQuests IN ASCII\n");*/
    if(req[0]=='G' &&req[1]=='E'&& req[2]=='T')
{   printf("\nEntered GET\n");  

if(strstr(req,"username")==NULL){
if(strstr(req,"/Login.html HTTP/1.1")!=NULL)
    {
        printf("\nenetered login\n");
        ReadFrom("Login",buffer,c1);
        CLOSESOCKET(c1);
    }

    else if(strstr(req,"/Logout.html HTTP/1.1")!=NULL)
    {   
        CLOSESOCKET(c1);
        CLOSESOCKET(Server);
        printf("closed");
        exit(0);
    }

    else if(strstr(req,"/Signup.html HTTP/1.1")!=NULL)
    {
        printf("\nenetered signup\n");
        ReadFrom("Signup",buffer,c1);
        CLOSESOCKET(c1);
        printf("WHY CLOSE");
    }
    else
    {
    printf("\nenetered index\n");
            ReadFrom("index",buffer,c1);
    }



}
else {
    printf("INSTEAD \n");
    if(strstr(req,"/Move.html HTTP/1.1")!=NULL)
    {
        printf("\nenetered Move\n");
        MainRead(0,buffer,c1,1,USERNAMEnum);
    }
    else if(strstr(req,"/Read.html?Category=")!=NULL)
    {char Category[20];
        char Patid[20];
        wordify(req,"Category=","?",Category);
        wordify(req,"Patid=","?",Patid);
        ReadFrom("Read",buffer,c1);

    }
    else if(strstr(req,"/Write.html HTTP/1.1")!=NULL)
    {
        printf("\nenetered write\n");
        char Category[20];
        char Patid[20];
        wordify(req,"Category=","?",Category);
        wordify(req,"Patid=","?",Patid);
        ReadFrom("Read",buffer,c1);

    }
    else if(strstr(req,"/New.html HTTP/1.1")!=NULL)
    {
        printf("\nenetered New\n");

        MainRead(0,buffer,c1,4,USERNAMEnum);
    }
    else if(strstr(req,"/Logout.html HTTP/1.1")!=NULL)
    {   
        CLOSESOCKET(c1);
        CLOSESOCKET(Server);
        printf("closed");
        exit(0);
    }
    else{
    MainRead(0,buffer,c1,0,USERNAMEnum);
    }   
    }


}
    else if(req[0]=='P' && req[1]=='O' && req[2]=='S' && req[3]=='T')
{printf("came here to POST:\n");
    if(strstr(req,"/table1.html HTTP/1.1")!=NULL)
    {printf("came here to TABLE\n");

    printf("GOT::TABLE\n");
    wordify(req,"Sno=","&",User.doctor_name);
    StoI(User.doctor_name,&User.serialno);
    wordify(req,"username=","&",User.username); 
    wordify(req,"&pswd=","\b",User.password);
    if(Login(User)==0){
        //Code for error
    }
    else{
        ItoS(USERNAMEnum,Login(User));
    }
    MainRead(0,buffer,c1,0,USERNAMEnum);
    printf("LOL");

    }else if (strstr(req,"/Signup.html HTTP/1.1")!=NULL){
        printf("\nenetered SIgnup in POST\n");
    wordify(req,"Sno1=","&",User.doctor_name);
    StoI(User.doctor_name,&User.serialno);
    wordify(req,"&Name=","&",User.doctor_name);
    wordify(req,"&Phoneno=","&",User.username);
    StoI(User.username,&User.Phoneno);
    wordify(req,"&Hospitalname=","&",User.hostipal_name);
    wordify(req,"&State1=","&",User.state);
    wordify(req,"&username1=","&",User.username);
    wordify(req,"&pswd1=","\b",User.password);
    printf("THE NUMBER:: %u ul \n",User.serialno);
    Signup(User);

        ReadFrom("Login",buffer,c1);
        printf("Signup success\n"); 
        CLOSESOCKET(c1);
    }

}
/*  else{
        CLOSESOCKET(c1);
        CLOSESOCKET(Server);
        printf("closed");
        exit(0);
        }*/

    }

    return 1;

}

【问题讨论】:

  • recv 返回 0 通常意味着远程对等方执行的优雅套接字关闭。我不清楚的是,在关闭之前您是否获得了预期的数据。
  • 在被动延迟后,当客户端发送数据时,套接字关闭,但对于来自的 Post 请求,客户端在关闭前收到预期的数据
  • 所以你所经历的可能是预期的关闭。服务器说“我发送了您请求的所有数据。祝您有美好的一天。PS:如果您需要更多连接,请打开一个新套接字”。这是我多年来没有处理过的事情,但如果我没记错的话,闭包行为是可以从服务器端以某种方式配置的。
  • 谢谢你的提示,但如果你注意到了,这里发布的代码是服务器代码,我不会关闭绑定到端口 80 的 Server_listen 套接字,我正在使用我的浏览器作为一个客户端来访问它。尽管如此,服务器套接字还是关闭了,我想知道这个原因。感谢您的努力
  • 在调用它们的位置之后定义的所有函数,都需要在 #include 语句之后的原型。否则,编译器会输出大量警告和错误消息。也就是说,贴出来的代码不能编译!

标签: c sockets http


【解决方案1】:

如果不调用setsockopt() 使套接字可重用,套接字将关闭,通常在第一次通信之后。

建议:

if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) < 0)
{
    perror( "setsockopt with SO_REUSEADDR failed" );
    exit( EXIT_FAILURE );
}

【讨论】:

    猜你喜欢
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-17
    • 2018-12-18
    • 2011-07-13
    • 2021-07-01
    • 2013-01-19
    相关资源
    最近更新 更多