如何使用C中的套接字将客户端连接到IRC服务器

如何使用C中的套接字将客户端连接到IRC服务器,c,sockets,winsock,irc,C,Sockets,Winsock,Irc,我正在编写一个要连接到IRC.hackerzvoice.net的IRC客户端。 我已经阅读了这里关于Stackoverflow的类似文章,但仍然没有发现我的代码中可能存在的错误。 在发送NICK和USER消息后,我仍然会收到相同的注册超时错误 La socket 280 est ouverte en TCP/IP. Connexion a 212.83.153.145 sur le port 6667 68 octets ont ete recus texte recu : :irc.hacke

我正在编写一个要连接到IRC.hackerzvoice.net的IRC客户端。 我已经阅读了这里关于Stackoverflow的类似文章,但仍然没有发现我的代码中可能存在的错误。 在发送NICK和USER消息后,我仍然会收到相同的注册超时错误

La socket 280 est ouverte en TCP/IP.
Connexion a 212.83.153.145 sur le port 6667
68 octets ont ete recus
texte recu : :irc.hackerzvoice.net NOTICE Auth :*** Looking up your hostname...
16 octets envoyes au serveur
texte envoye : NICK parallel
.30 octets envoyes au serveur
texte envoye : USER parallel * * :parallel
.99 octets ont ete recus
texte recu : :irc.hackerzvoice.net NOTICE Auth :*** Found your hostname (catv-89-132-88-100.catv.broadband.hu)
92 octets ont ete recus
texte recu : ERROR :Closing link: (unknown@catv-89-132-88-100.catv.broadband.hu) [Registration timeout]
d.hu)
0 octets ont ete recus
texte recu : ERROR :Closing link: (unknown@catv-89-132-88-100.catv.broadband.hu) [Registration timeout]
d.hu)
这是我的密码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "root_me_1.h"
 
 
int main()
{
    // Si la plateforme est Windows
    #if defined (WIN32)
        WSADATA WSAData;
        WSAStartup(MAKEWORD(2,2), &WSAData); // sert à initialiser la bibliothèque WinSock
    #endif
 
    // socket et interface de connexion
    SOCKET sock;
    SOCKADDR_IN sin; // structure
 
    char buffer[TAILLE_MAX] = "";
    int nOctetsRecus = 0;
    int nOctetsEnvoyes = 0;
    int tailleBuffer = 0;
    int boucle = 1;
 
    // on crée une socket utilisant protocole TCP/IP
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock == INVALID_SOCKET)
        printf("Erreur, socket non valide");
    printf("La socket %d est ouverte en TCP/IP.\n", sock);
 
    // on configure l'interface de connexion
    sin.sin_addr.s_addr = inet_addr("212.83.153.145"); // adresse IP du serveur IRC
    sin.sin_family = AF_INET;
    sin.sin_port = htons(PORT); // sin_port et sin_addr doivent être en Network Byte Order // htons() convertit un entier court depuis l'ordre des octets de l'hôte vers celuidu réseau (host to network short)
 
    if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR) // si le client réussit à se connecter au serveur
        printf("Connexion a %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
    else
        printf("Erreur de connexion.");
 
 
    // on reçoit les données envoyées par le serveur
    nOctetsRecus = recv(sock, buffer, TAILLE_MAX, 0);
    if(nOctetsRecus != SOCKET_ERROR)
    {
        printf("%d octets ont ete recus\n", nOctetsRecus);
        printf("texte recu : %s", buffer);
    }
    else
        printf("Les donnees n'ont pas ete recues");
 
 
    // le client envoie des données au serveur
    sprintf(buffer, "NICK parallel\r\n");
    tailleBuffer = strlen(buffer)+1; // taille de la chaine + '\0'
 
    nOctetsEnvoyes = send(sock, buffer, tailleBuffer, 0);
    if(nOctetsEnvoyes != SOCKET_ERROR)
    {
        printf("%d octets envoyes au serveur\n", nOctetsEnvoyes);
        printf("texte envoye : %s", buffer);
    }
    else
        printf("Erreur : donnees non envoyees au serveur");
 
    // le client envoie des données au serveur
    sprintf(buffer, "USER parallel * * :parallel\r\n");
    tailleBuffer = strlen(buffer)+1; // taille de la chaine + '\0'
 
    nOctetsEnvoyes = send(sock, buffer, tailleBuffer, 0);
    if(nOctetsEnvoyes != SOCKET_ERROR)
    {
        printf("%d octets envoyes au serveur\n", nOctetsEnvoyes);
        printf("texte envoye : %s", buffer);
    }
    else
        printf("Erreur : donnees non envoyees au serveur");
 
 
    // on reçoit les données envoyées par le serveur
    nOctetsRecus = recv(sock, buffer, TAILLE_MAX, 0);
    if(nOctetsRecus != SOCKET_ERROR)
    {
        printf("%d octets ont ete recus\n", nOctetsRecus);
        printf("texte recu : %s", buffer);
    }
    else
        printf("Les donnees n'ont pas ete recues");
 
 
    // on ferme la connexion
    closesocket(sock);
 
 
    #if defined (WIN32)
        WSACleanup(); // libère les ressources allouées par la fonction WSAStartup()
    #endif
 
    getchar();
 
    return EXIT_SUCCESS;
}
你知道这个问题吗

谢谢。

这就是问题所在

sprintf(buffer, "NICK hoeplem\r\n");
tailleBuffer = strlen(buffer)+1;
因为strlenbuffer+1是空终止符的一个字节,所以不应将空终止符“\0”发送到服务器,并且strlen返回不包含空终止符的字符串长度。字符串的实际长度。如果服务器读取该字节,它可能希望“\r\n”刷新缓冲区并处理该命令,因此在最后一个命令之后它将永远等待

应该是

tailleBuffer = sprintf(buffer, "NICK hoeplem\r\n");
这样就完美了

您可能还希望检查和/或滚动您自己的dprintf,以避免每次短跑


另外,最好将每个命令作为一个带有参数的函数,并简单地调用command_Xsock、parameters。。。对于每一个可能的命令,这样您的代码都会更加健壮。

您的错误处理是错误的,您会检查可能的错误,但仍然继续执行程序。可能大多数阅读此命令的人不会说/读法语。另外,“printfetexte recu:%s,buffer;”如果读取TAILLE_MAX chars,则将失败-缓冲区不保证NUL终止。我建议阅读TAILLE_MAX-1 chars。注意:我添加了winsock标记,因为您似乎使用了windows套接字实现。没有DV,但也没有得到您的答案。如果服务器的协议是面向行的,我会发送字符串的确切长度。我不会发送0-terminator。这就是你想表达的吗?我现在明白你的意思了。不过我还是要明确地提到该字节是哪个字节。'\0'确实带来了问题,现在它可以工作了。谢谢