简单的网络服务器无法正常工作

Jojojoppe

我正在尝试用C语言编写一个网络服务器。我知道我可以为此使用许多不同的库,但是我希望它只能与winsock一起运行。服务器和客户端可以来回发送数据,但是无法加载网页。每次我收到“服务器无法访问”消息,但在服务器上却收到消息,指出正文已发送。我究竟做错了什么?

编辑我正在使用Chrome和Microsoft Edge

#include <stdio.h>
#include <conio.h>

#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib")

void error(const char* err){
    printf("ERROR: %s\n", err);
    exit(1);
}

char* readline(SOCKET s){
    FILE * f = tmpfile();
    char rec;
    int i=0;
    while(recv(s, &rec, 1, 0)>0){
        i++;
        if(rec!='\r' && rec!='\n')
            fwrite(&rec, 1, 1, f);
        if(rec=='\r' || rec=='\n')
            break;
    }
    if(i==0){
        fclose(f);
        return NULL;
    }
    fseek(f, 0, SEEK_END);
    long long size = ftell(f);
    fseek(f, 0, SEEK_SET);
    char * d = (char*) malloc(size);
    memset (d,0,size);
    fread(d, 1, size, f);
    fclose(f);
    return d;
}

void flush(SOCKET s){
    while(recv(s, NULL, 1, 0)>0){
    }
}

void main(){

    // CREATE SERVER
    WSADATA wsa;
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
        error("WSAStartup");
    SOCKET s;
    if((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
        error("socket");
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(80);
    if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
        error("bind");

    // SERVER CREATED
    while(1){
        listen(s, 1);
        int c = sizeof(struct sockaddr_in);
        SOCKET csock;
        struct sockaddr_in client;
        if((csock = accept(s, (struct sockaddr*)&client, &c))==INVALID_SOCKET)
            continue;
        char *client_ip = inet_ntoa(client.sin_addr);
        printf("Incomming connection: %s\n", client_ip);

        char * head = readline(csock);
        if(strncmp(head, "GET", 3)==0){
            flush(csock);

            char response[] = "HTTP/1.1 200 OK\r\n"
            "Content-Type: text/html\r\n\r\n"
            "<html><head><title>test</title>"
            "</head><body>Test123</body></html>";
            send(csock, response, strlen(response), 0);
            printf("%s\n", "HTML body sended");
        }else if(strncmp(head, "HEAD", 4)==0){
            flush(csock);

            char response[] = "HTTP/1.1 200 OK\r\n"
            "Content-Type: text/html\r\n\r\n";
            send(csock, response, strlen(response), 0);
            printf("%s\n", "HTML head sended");
        }

        closesocket(csock);
    }

    closesocket(s);
    WSACleanup();
}
弗兰基

该功能:

void flush(SOCKET s){
    while(recv(s, NULL, 1, 0)>0){
    }
}

在客户端(浏览器)重置连接之前,不读取任何内容以使所有内容都进入缓冲区。如果您检查返回的值,send(csock, response, strlen(response), 0);则会看到SOCKET_ERROR通话WSAGetLastError()将返回

代码0x2745 =主机中的软件中止了已建立的连接。

您用来读取套接字的方式确实很丑陋!使用ioctlsocket()withFIONREAD获得要读取的字符数:

char* readline(SOCKET s)
{
    size_t MsgLen = 0;
    char *Msg = NULL;
    unsigned long Len;
    int res;
    while (0 == (res=ioctlsocket(s, FIONREAD, &Len)))
    {
        if (SOCKET_ERROR == Len)
        {
            if (Msg)
            {
                free(Msg);
                Msg = NULL;
            }
            return NULL;
        }

        if (!Len && MsgLen)
            break;

        if (!Msg)
            Msg = malloc(Len);
        else
            Msg = realloc(Msg, MsgLen + Len);

        recv(s, Msg+MsgLen, Len, 0);

        MsgLen += Len;
    }
    return Msg;
}

要使用它来修复您的源:

char response[] = "HTTP/1.1 200 OK\r\n"
                  "Content-Type: text/html\r\n\r\n"
                  "<html><head><title>test</title>"
                  "</head><body>Test123</body></html>\r\n";

char response[] = "HTTP/1.1 200 OK\r\n"
                  "Content-Type: text/html\r\n\r\n";

int main(int argc, char *argv[])
{

    // CREATE SERVER
    WSADATA wsa;
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
        error("WSAStartup");
    SOCKET s;
    if((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
        error("socket");
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(80);
    if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
        error("bind");

    // SERVER CREATED
    while(1){
        listen(s, 1);
        int c = sizeof(struct sockaddr_in);
        SOCKET csock;
        struct sockaddr_in client;
        if((csock = accept(s, (struct sockaddr*)&client, &c))==INVALID_SOCKET)
            continue;
        char *client_ip = inet_ntoa(client.sin_addr);
        printf("Incoming connection: %s\n", client_ip);

        char * head = NULL;
        do
        {
            head = readline(csock);
        } while (!head);
        if(strncmp(head, "GET", 3)==0)
        {
            if (SOCKET_ERROR  == send(csock, response, strlen(response), 0))
            {
                WSAGetLastError();
            }
            printf("%s\n", "HTML body sended");
        }
        else
            if(strncmp(head, "HEAD", 4)==0)
            {
                send(csock, response, strlen(response), 0);
                printf("%s\n", "HTML head sended");
            }

        closesocket(csock);
    }

    closesocket(s);
    WSACleanup();
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么OAuth无法在网络服务器上工作?

来自分类Dev

双向网络服务器

来自分类Dev

聚合物; 本地网络服务器正常工作,投递箱无效。怀疑者:https

来自分类Dev

有没有可以编译的简单Python网络服务器?

来自分类Dev

如何设置支持开启和关闭的简单网络服务器

来自分类Dev

访问我的网络服务器的工作原理...从我的Intranet内部访问除外

来自分类Dev

Phpmailer 不在网络服务器上工作

来自分类Dev

Esp01 Wifi 热点 + 网络服务器不工作

来自分类Dev

网络服务器的out.flush()问题

来自分类Dev

与网络服务器相关的autoIndex是什么?

来自分类Dev

设置安全的网络服务器

来自分类Dev

设置动态网络服务器

来自分类Dev

保持我的生产网络服务器更新

来自分类Dev

网络服务器上的Memcached

来自分类Dev

将android应用与网络服务器连接

来自分类Dev

在Yaws网络服务器上上传进度

来自分类Dev

元素在网络服务器上消失

来自分类Dev

网络服务器显示错误的布局

来自分类Dev

网站/网络服务器容错-最佳做法

来自分类Dev

oAuth2 的 Java 网络服务器

来自分类Dev

网络服务器 php 和 mysql 滞后

来自分类Dev

自动启动网络服务器和程序

来自分类Dev

Apache 网络服务器如何检测 CNAME

来自分类Dev

使用ajax从网络服务器获取响应

来自分类Dev

无法从自己的ipv6子网访问网络服务器,但从外部访问

来自分类Dev

无法配置oracle 11g网络服务器

来自分类Dev

无法连接到在 Ubuntu 20.04 无头服务器上运行的 Apache 网络服务器

来自分类Dev

在网络服务器上时,IE / FF无法找到可播放HTML5的视频。-Chrome可以正常播放

来自分类Dev

网站在本地工作,但不在 NodeJS 网络服务器上,初学者

Related 相关文章

热门标签

归档