0

我正在用 C 语言编写 IRC 客户端。在连接服务器时遇到了一些问题。当我运行程序时,我得到以下信息:

输出

Set Fully Qualified host Domain Name(human readable):  ::automaticaly provided::

Set the port number of the server You want to connect to: ::automaticaly provided::

Destination server IP: 88.190.23.245

Socket descriptor: 3

Connection has been successfully established

Peer's IP is: 88.190.23.245
Peer's port is: 5190

:irc2.gbatemp.net NOTICE AUTH :*** Looking up your hostname...

:irc2.gbatemp.net NOTICE AUTH :*** Found your hostname (cached)

Type Your nick name: ::automaticaly provided::

Type Your user name: ::automaticaly provided::

(10-20 seconds break here and than what follows down here)


ERROR :Closing Link: thisIsMyNickNameXXXa[85.221.165.54] (Ping timeout)

temp.net NOTICE AUTH :*** Found your hostname (cached)

ERROR :Closing Link: thisIsMyNickNameXXXa[85.221.165.54] (Ping timeout)

temp.net NOTICE AUTH :*** Found your hostname (cached)

ERROR :Closing Link: thisIsMyNickNameXXXa[85.221.165.54] (Ping timeout)

temp.net NOTICE AUTH :*** Found your hostname (cached)

.......
.............
...................

==================================================== ===========

::automaticaly provided::- 表示现在由程序传递,所以我不必多次输入。

顺便提一句。正在连接到 irc.gbatemp.net:5190(就我而言,不需要密码)

在提供必要的数据后 10-20 秒发生中断(我在 OUTPUT 部分指定),然后 ERROR temp.net 部分跟随广告无限(我用点标记)

所以问题的主要部分是我应该如何以及何时发送 PONG 消息以响应 PING ?我做了我的研究,但仍然无法做到。为什么我在 STDOUT 中看不到 PING 消息?

我正在提供负责输出和 PINGPONG 部分的代码(已注释)(目前的主要问题是 PING PONG,因为错误状态为 PING TIMEOUT)可能是 while(1) 循环还不完美,但我想它是另一个主题的主题)代码如下:

    int readReady=0;
    int writeReady=0;
    pid_t pID;
    char buf[1024];     //I/O buffer (?)
    pid_t sID;
    char *NICK = "NICK thisIsMyNickNameXXXa\n\r";
    char *USER = "USER tomaazrxtc 8 * :nameandsurname";
    char ping[512];
    char *change;

    pID=fork();
            if(pID < 0){
                //failed to execute fork()
                perror("Error while forking");
                getchar();getchar();
                exit(1);
            }
            if(pID > 0){
                exit(0);
                }
            //child down here
                //setting new session
                sID = setsid();
                if(sID < 0){
                    perror("Error while setting new session");
                    getchar();getchar();
                    exit(1);
                }

//---------receiving NOTICE AUTH :*** part-------------------------------

                if(recv(sockfd, buf, 1024,0)>0){
                printf(buf);
                }
                else{
                    perror("Error while receiving data");
                }

//---------providing and sending NICK and USERNAME-----------------------

                printf("Type Your nick name: \n");
                //scanf(nickname); pamietaj zeby zapewnic podawanie tylko nicku, a format handler zrobic osobno

                send(sockfd, NICK, strlen(NICK), 0);

                printf("Type Your user name: \n");
                //scanf(username); pamietaj zeby zapewnic podawanie tylko nicku, a format handler zrobic osobno

                send(sockfd, USER, strlen(USER), 0);

//--------Shoudnt I receive PING message just here ?????-----------------

                recv(sockfd, buf, strlen(buf), 0);
                printf(buf);

//--------PONG'ing function which I havent tested yet since i cant see PING message----

                recv(sockfd, ping, 512,0);
                if(strstr(ping, "PING")){
                    change = strstr(ping, "PING");
                    strncpy(change, "PONG", 4);
                    send(sockfd, ping, 512, 0);
                    }

//-------------------------------------------------------------------------


                while(1){
                    //sleep(1);
                    if((readReady = readReadiness(sockfd))==0){    //nothing to recv
                        if((writeReady = writeReadiness(sockfd))>0){  //sending is possible
                                scanf(buf);
                                send(sockfd, buf, strlen(buf), 0);
                                continue;
                        }
                        else
                            continue; //if there s no data to read and cant send (is it even possible?)
                    }
                    else{ //if there s some data to recv() on the socket buffer
                        recv(sockfd, buf, strlen(buf), 0);
                        printf(buf);
                        continue;
                    }
                }
//--------------------------------------------------------------------------

行。以后我会把这个问题留给其他人并提供答案。这很琐碎。

我刚刚在 USER 变量的末尾添加了 \n\r (就像在 NICK 字符串中一样)。像魅力一样连接!

终于 : ))

4

1 回答 1

3

因此,我立即发现的一些问题是:

  1. NICK未正确终止。应该是\r\n
  2. USER根本没有终止,它应该以\r\n.
  3. 当您发送 ping 响应时,您的硬编码大小为512. send()不适用于字符串,它适用于原始数据。所以,你也会在这里传递很多垃圾。您需要根据收到的内容传递长度。
  4. printf(buf);不安全。任何碰巧包含格式说明符的传入字符串都会导致printf()尝试解释它们(这被称为“格式字符串漏洞”)。它们应该被替换为printf("%s", buf);以安全的方式实现相同的行为。
  5. 通常,您的代码假定从 IRC 接收到的消息是 nul 终止的。他们不是。您应该使用 的返回值recv()来了解您收到了多少数据。
  6. strlen()用于确定缓冲区的大小。此函数计算字符串的长度,而不是缓冲区的大小。您应该改用sizeof运算符。
  7. 我不确定scanf(buf);应该做什么,但几乎可以肯定这不是你想要的。也许你在找fgets()
  8. recv()对 ping 的调用发生在 for 之后buf。你怎么知道什么时候会发生,会持续多久?似乎您应该始终使用相同的缓冲区。
于 2012-05-07T13:10:17.843 回答