连接到 IRC 服务器 C++ Windows 10 Visual Studio

Posted

技术标签:

【中文标题】连接到 IRC 服务器 C++ Windows 10 Visual Studio【英文标题】:Connecting to IRC Server C++ Windows 10 Visual Studio 【发布时间】:2018-07-18 23:00:14 【问题描述】:

所以我对 C++/C 还很陌生,大约一周前才学会这门语言,所以我有点迷茫。我正在尝试构建一个 IRC 客户端来连接到服务器,但我似乎无法让它工作。我使用 Visual Studio 作为我的 IDE,并按照此处列出的说明进行 Socket 连接:https://docs.microsoft.com/en-us/windows/desktop/winsock/complete-client-code

// Testing.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <iostream>
#include <string>

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

using namespace std;

SOCKET ConnectSocket = INVALID_SOCKET;

void SendData(string s) 
    if (send(ConnectSocket, s.c_str(), sizeof(s.c_str()), 0) == SOCKET_ERROR) 
        cout << "send failed: " << WSAGetLastError() << endl;
        closesocket(ConnectSocket);
        WSACleanup();
    
    else  cout << s << endl; 


int main()

    WSADATA wsaData;

    // Initialize Winsock
    if (WSAStartup(MAKEWORD(2, 2), &wsaData)) 
        printf("WSAStartup failed");
        system("pause");
    
    else  cout << "WinSock Started" << endl; 

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

    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    // Resolve the server address and port

    if (getaddrinfo("38.229.70.22", "6665", &hints, &result)) 
        cout << "GetAddrInfo FAILED" << endl;
        WSACleanup();
        system("pause");
    

    // Attempt to connect to the first address returned by
    // the call to getaddrinfo
    ptr = result;

    // Create a SOCKET for connecting to server
    ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
        ptr->ai_protocol);

    if (ConnectSocket == INVALID_SOCKET) 
        cout << "Error at socket(): " << WSAGetLastError() << endl;
        freeaddrinfo(result);
        WSACleanup();
        system("pause");
    

    // Connect to server.
    if (connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen) == SOCKET_ERROR) 
        closesocket(ConnectSocket);
        ConnectSocket = INVALID_SOCKET;
    

    // Should really try the next address returned by getaddrinfo
    // if the connect call failed
    // But for this simple example we just free the resources
    // returned by getaddrinfo and print an error message

    freeaddrinfo(result);

    if (ConnectSocket == INVALID_SOCKET) 
        cout << "Unable to connect to server!\n" << endl;
        WSACleanup();
        system("pause");
    
    else  cout << "CONNECTED!!!" << endl; 

    string pass = "PASS none\r\n", nick = "NICK TestUserFoo\r\n", user = "USER guest 0 * :TestUserFoo\r\n", join = "JOIN #etc";
    SendData(pass);
    SendData(nick);
    SendData(user);
    SendData(join);

    char recvbuf[512];

    int iResult;

    cout << "Data Sent" << endl;

    // shutdown the connection for sending since no more data will be sent
    // the client can still use the ConnectSocket for receiving data
    /*iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) 
        printf("shutdown failed: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    */

    // Receive data until the server closes the connection
    do 
        iResult = recv(ConnectSocket, recvbuf, sizeof(recvbuf), 0);
        if (iResult > 0)
            cout << "Bytes received: " << iResult << endl << recvbuf << endl;
        else if (iResult == 0)
            cout << "Connection closed\n";
        else
            cout << "recv failed: " << WSAGetLastError() <<endl;
     while (iResult > 0);

    system("pause");

我决定连接到freenode上的一个空频道,并通过ping它获得了chat.freenode.net的IP。当我连接时,这是我的输出:

WinSock Started
CONNECTED!!!
PASS none

NICK TestUserFoo

USER guest 0 * :TestUserFoo

JOIN #etc
Data Sent
Bytes received: 62
:card.freenode.net NOTICE * :*** Looking up your hostname...
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╚Σv
Bytes received: 103
:card.freenode.net NOTICE * :*** Checking Ident
:card.freenode.net NOTICE * :*** Found your hostname
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╚Σv

似乎我为 PASS NICK 和 USER 发送的命令没有被解释或正确发送到 IRC 服务器,因为我没有收到回复。怎么回事?

【问题讨论】:

【参考方案1】:

你的问题是:

sizeof(s.c_str())

if (send(ConnectSocket, s.c_str(), sizeof(s.c_str()), 0) == SOCKET_ERROR) 

sizeof 运算符返回 char* 的大小(可能是 4 字节或 8 字节,具体取决于它是 32 位还是 64 位应用程序)。

你想把它改成:

if (send(ConnectSocket, s.c_str(), s.size(), 0) == SOCKET_ERROR) 

【讨论】:

以上是关于连接到 IRC 服务器 C++ Windows 10 Visual Studio的主要内容,如果未能解决你的问题,请参考以下文章

c++ winsock irc客户端问题

如何在 IRC 服务器中发送消息聊天?

连接到 IRC 时的套接字问题

我可以从使用 c++ 和 windows 连接到服务器的套接字获得啥信息?

连接到 Twitch IRC 聊天

多线程在 C++ 中的 Windows 中将多个客户端连接到单个服务器