0

我有一个在 Windows 下用 C 编写的服务器,但我似乎只能从也连接到我的计算机所连接的路由器的机器上连接到它。任何想法为什么?这是我的代码:

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>

#pragma comment(lib,"Ws2_32.lib")

#define PORT "1234"
#define BUFLEN 512

DWORD ErrorMessage(char* msg, int error)
{
    printf("ErrorMessage: %s\nCodErr: %d\n", msg, error);
    return -1;
}

void PrintArray(char* v, unsigned int len)
{
        for(unsigned int i = 0 ; i < len ; i++)
    printf("%c",v[i]);
    printf("\n");
}

DWORD WINAPI ClientHandler(LPVOID lpParam)
{
SOCKET ClientSocket = *((SOCKET*)lpParam);

char recvbuf[BUFLEN];

int iResult,iSendResult;

do
{
    iResult = recv(ClientSocket, recvbuf, BUFLEN, 0);

    if(iResult > 0)
    {
        PrintArray(recvbuf,iResult);

        iSendResult = send(ClientSocket, recvbuf, iResult, 0);

        if(iSendResult == SOCKET_ERROR)
        {
            closesocket(ClientSocket);
            WSACleanup();
            return ErrorMessage("send",WSAGetLastError());
        }
    }

    else if(iResult == 0)
        printf("Connection closing...\n");
    else
    {
        closesocket(ClientSocket);
        WSACleanup();
        return ErrorMessage("recv",WSAGetLastError());
    }
}
while(iResult > 0);

return 0;
}

int main()
{
WSADATA wsaData;

int iResult;

iResult = WSAStartup(MAKEWORD(2,2),&wsaData);

if(iResult != 0)
{
    printf("WSAStartup failed and with error code: %d\n",iResult);
    return ErrorMessage("WSAStartup",GetLastError());
}

struct addrinfo *result = NULL, *ptr = NULL, hints;

memset(&hints,0,sizeof(hints));

hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;

iResult = getaddrinfo(NULL,PORT,&hints,&result);

if(iResult != 0)
{
    printf("getaddrinfo failed %d\n",iResult);
    WSACleanup();
    return -1;
}

SOCKET ListenSocket = INVALID_SOCKET;

ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);

if(ListenSocket == INVALID_SOCKET)
{
    freeaddrinfo(result);
    WSACleanup();
    return ErrorMessage("socket",WSAGetLastError());
}

iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);

if(iResult == SOCKET_ERROR)
{
    freeaddrinfo(result);
    closesocket(ListenSocket);
    WSACleanup();
    return ErrorMessage("bind", WSAGetLastError());
}

freeaddrinfo(result);

if(listen(ListenSocket,5) == SOCKET_ERROR)
{
    closesocket(ListenSocket);
    WSACleanup();
    return ErrorMessage("listen",WSAGetLastError());
}

SOCKET ClientSocket = INVALID_SOCKET;

sockaddr sa;

while(true)
{
    ClientSocket = accept(ListenSocket, &sa /*NULL*/, NULL);

    if(ClientSocket == INVALID_SOCKET)
    {
        closesocket(ListenSocket);
        WSACleanup();
        return ErrorMessage("accept",WSAGetLastError());
    }

    printf("New client arrived...\n");

    if(CreateThread(NULL, 0, ClientHandler, &ClientSocket, 0, NULL) == NULL)
        ErrorMessage("CreateThread",GetLastError());
}

iResult = shutdown(ClientSocket,SD_BOTH);

if(iResult == SOCKET_ERROR)
{
    closesocket(ClientSocket);
    closesocket(ListenSocket);
    WSACleanup();
    return ErrorMessage("shutsown",WSAGetLastError());
}

closesocket(ListenSocket);
WSACleanup();

return 0;
}
4

2 回答 2

1

我无法遵循您的代码,但通常我使用bindwith htons。在您的代码中,如何将字符串“1234”转换为数值并不明显。我在端口 1234 上编写了一个非常粗糙的简单 Web 服务器,它只是提供一个虚拟的“Hello World”页面。已删除所有验证以保持示例简短:

#include "stdafx.h"
#include <tchar.h>
#include <windows.h>
#include <winsock.h>

#pragma comment(lib, "wsock32.lib")

int _tmain(int argc, _TCHAR* argv[])
{
    WSADATA wsaData = {0};
    WSAStartup(0x202, &wsaData);
    SOCKET serverSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    SOCKADDR_IN sin = {0};
    sin.sin_family = PF_INET;
    sin.sin_port = htons(1234);
    sin.sin_addr.s_addr = INADDR_ANY;
    bind(serverSocket, (LPSOCKADDR) &sin, sizeof(sin));
    listen(serverSocket, 1);
    SOCKET clientSocket = accept(serverSocket, NULL, NULL);
    while (clientSocket != INVALID_SOCKET)
    {
        char request[1024] = {0};
        recv(clientSocket, request, 1024, 0);
        static char html[] =
            "HTTP/1.1 200 OK\n"
            "Content-Type: text/html\n"
            "\n"
            "<HTML><HEAD><TITLE>Hello World!</TITLE></HEAD><BODY>Hello World!</BODY></HTML>\n\n";
        send(clientSocket, html, sizeof(html), 0);
        closesocket(clientSocket);
        clientSocket = accept(serverSocket, NULL, NULL);
    }
    closesocket(serverSocket);
    WSACleanup();
    return 0;
}
于 2012-09-07T05:39:19.843 回答
0

问题不在您的程序中。问题出在路由器的配置上。

尝试从外部连接到计算机上的其他一些 TCP/IP 服务。

于 2012-09-06T19:12:46.417 回答