1

我有以下用纯 C 语言编写的简单 winsock 服务器:

#include <windows.h>
#include <winsock.h>
#include <stdio.h>

#define NETWORK_ERROR -1
#define NETWORK_OK     0

int IP = INADDR_ANY;
int port = 8888;

SOCKET listeningSocket;
SOCKET client;

void error(const char *);
void error(const char *functionName) {
    char errorMsg[92];
    ZeroMemory(errorMsg, 92);

    sprintf(errorMsg, "Call to %s returned error %d!", (char *)functionName, WSAGetLastError());

    MessageBox(NULL, errorMsg, "socketIndication", MB_OK);

    closesocket(client);
    closesocket(listeningSocket);
    WSACleanup();
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nShow) {

    WSADATA wsaData;
    int nret;

    WSAStartup(MAKEWORD(1, 1), &wsaData);

    char hostName[80];
    if(gethostname(hostName, sizeof(hostName)) == SOCKET_ERROR) {
        error("gethostname()");
        return NETWORK_ERROR;
    }

    printf("Started Server\n");
    printf("Running on: %s\n", hostName);

    listeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if(listeningSocket == INVALID_SOCKET) {
        error("socket()");
        return NETWORK_ERROR;
    }

    SOCKADDR_IN serverInfo;

    serverInfo.sin_family = AF_INET;
    serverInfo.sin_addr.s_addr = INADDR_ANY;

    serverInfo.sin_port = htons(port);

    nret = bind(listeningSocket, (LPSOCKADDR)&serverInfo, sizeof(struct sockaddr));

    if(nret == SOCKET_ERROR) {
        error("bind()");
        return NETWORK_ERROR;
    }

    while(client != INVALID_SOCKET) {
        nret = listen(listeningSocket, 10);
        printf("Listening for incoming requests\n");

        if(nret == SOCKET_ERROR) {
            error("listen()");
            return NETWORK_ERROR;
        }

        client = accept(listeningSocket, NULL, NULL);

        char buffer[256];
        ZeroMemory(buffer, 256);

        strcpy(buffer, "Pretend this is important data.");

        nret = send(client, buffer, strlen(buffer), 0);

        if(nret == SOCKET_ERROR) {
            error("send()");
            return NETWORK_ERROR;
        }

        printf("Sent some data\n");

        closesocket(client);
    }

    error("accept()");
    return NETWORK_ERROR;
}

大部分内容来自本教程:

http://johnnie.jerrata.com/winsocktutorial/

但是,服务器似乎很受欢迎。当我在浏览器中访问 http://[My IP]:8888/ 时,有一半的时间我会得到“假装这是重要数据”的响应。正如预期的那样,但是另一半时间我得到“页面加载时与服务器的连接已重置”。或“Firefox 无法与 [My IP]:8888 的服务器建立连接。”。

那么我的代码有什么问题会导致这种情况吗?

4

1 回答 1

1

对 listen() 的调用应该在循环之外。循环中唯一需要的套接字调用是 accept() 来获取客户端套接字,以及读取、写入和最终关闭客户端套接字。

此外,如果您希望程序与 Firefox 一起工作,您必须实现 HTTP 协议的相关部分,http ://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol

于 2013-06-03T20:06:50.367 回答