3

win32 ソケット (winsock2) の使用方法を教えてくれるチュートリアルに従っています。「localhost」に接続する単純なソケットを作成しようとしていますが、(関数 connect() で) ローカル ホストに接続しようとするとプログラムが失敗します。

ローカルホストに接続するには管理者権限が必要ですか? 多分それが失敗する理由ですか?私のコードに問題があるのでしょうか?ポート 8888 と 8000 を試しましたが、どちらも失敗します。

また、ポートを 80 に変更して www.google.com に接続すると、接続できますが、応答が返されません。HTTP リクエストを送信していないためですか、それとも何らかの応答を返すつもりなのでしょうか?

これが私のコードです(インクルードは削除されています):

// Constants & Globals //
typedef unsigned long IPNumber;    // IP number typedef for IPv4
const int SOCK_VER    = 2;
const int SERVER_PORT = 8888;  // 8888
SOCKET mSocket        = INVALID_SOCKET;
SOCKADDR_IN sockAddr  = {0};
WSADATA wsaData;
HOSTENT* hostent;


int _tmain(int argc, _TCHAR* argv[])
{
    // Initialise winsock version 2.2
    if (WSAStartup(MAKEWORD(SOCK_VER,2), &wsaData) != 0)
    {
        printf("Failed to initialise winsock\n");
        WSACleanup();
        system("PAUSE");
        return 0;
    }

    if (LOBYTE(wsaData.wVersion) != SOCK_VER || HIBYTE(wsaData.wVersion) != 2)
    {
        printf("Failed to load the correct winsock version\n");
        WSACleanup();
        system("PAUSE");
        return 0;
    }

    // Create socket
    mSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (mSocket == INVALID_SOCKET)
    {
        printf("Failed to create TCP socket\n");
        WSACleanup();
        system("PAUSE");
        return 0;
    }


    // Get IP Address of website by the domain name, we do this by contacting(??) the Domain Name Server
    if ((hostent = gethostbyname("localhost")) == NULL)  // "localhost"  www.google.com
    {
        printf("Failed to resolve website name to an ip address\n");
        WSACleanup();
        system("PAUSE");
        return 0;
    }

    sockAddr.sin_port             = htons(SERVER_PORT);
    sockAddr.sin_family           = AF_INET;
    sockAddr.sin_addr.S_un.S_addr = (*reinterpret_cast <IPNumber*> (hostent->h_addr_list[0]));
    // sockAddr.sin_addr.s_addr=*((unsigned long*)hostent->h_addr);  // Can also do this

    // ERROR OCCURS ON NEXT LINE: Connect to server
    if (connect(mSocket, (SOCKADDR*)(&sockAddr), sizeof(sockAddr)) != 0)
    {
        printf("Failed to connect to server\n");
        WSACleanup();
        system("PAUSE");
        return 0;
    }

    printf("Got to here\r\n");
    // Display message from server
    char buffer[1000];
    memset(buffer,0,999);
    int inDataLength=recv(mSocket,buffer,1000,0);
    printf("Response: %s\r\n", buffer);

    // Shutdown our socket
    shutdown(mSocket, SD_SEND);

    // Close our socket entirely
    closesocket(mSocket);

    // Cleanup Winsock
    WSACleanup();

    system("pause");
    return 0;
}
4

3 に答える 3

3

接続ベースの TCP プロトコルを使用する場合は、接続開始要求に応答するためにポート 8888 でリッスンするアプリケーションなどの通信相手が必要になります ( TCP 用語ではSYN -パケット)。

管理者権限を必要とせずに、UNIXツールnetcat (他のOSでも利用可能)を使用できます...

nc -l 8888

...ローカルマシンのポート8888でリスニングソケットを開きます

ただし、UNIX システムでは、管理者権限なしではいわゆるwell-known ポートをリッスンすることはできません。

詳細については、TCP 接続のライフサイクルについてお読みください。

于 2011-11-26T09:38:57.157 に答える
1

接続先のポートで誰かがリッスンしている必要があります。着信接続をリッスンする小さなサーバー プログラムを作成してみてください。connect が成功した場合、明らかに Google に接続されていますが、HTTP リクエストを送信する必要があります (C から? - それは難しいでしょう)。

于 2011-11-26T10:14:55.577 に答える
0

localhost の TCP ポートに接続するには、誰かがあなたのマシンのそのポートをリッスンしている必要があります。

独自のサーバーを作成する以外に、いくつかのプログラムをリッスンさせる簡単な方法があります。マシンに「Simple TCP/IP Services」機能をインストールします。これにより、ポート 17 で「Quote of the day」サーバー、ポート 13 で Daytime サーバー、ポート 19 で Chargen サーバー、ポート 7 で echo サーバーが提供されます。

これをインストールするには、「プログラムと機能」または「プログラムの追加と削除」、または Windows で呼ばれるものに移動し、「Windows の機能の有効化または無効化」を選択して、「Simple TCPIP Services」を見つけてインストールします。リスト。

于 2013-10-03T16:10:39.683 に答える