简单的winsock服务器行为不可靠

时间:2013-06-03 19:49:49

标签: c winsock

我有以下用简单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:// [我的IP]:8888 /时,有一半时间我会得到回复&#34;假装这是重要的数据。&#34;按照预期,另一半时间我得到&#34;在页面加载时重置了与服务器的连接。&#34;或者&#34; Firefox无法在[我的IP]:8888与服务器建立连接。&#34;。

我的代码有什么问题导致这个问题吗?

1 个答案:

答案 0 :(得分:1)

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

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