2012-05-07 85 views
0

正在用C语言编写IRC客户端。并在连接到serwer时遇到了一些问题。 我碰到下面当我运行程序:如何连接到IRC服务器/解析C语言(提供代码)的IRC MSG/PING-PONG处理

输出

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:: - 表示由程序传递给现在,所以我不必输入很多次。

btw。我连接到irc.gbatemp.net:5190(无需密码,只要我担心)

在提供必要的数据10-20秒后发生中断(我在OUTPUT部分中指定)并且ERROR temp.net部分如下广告infinitum(我用点划线)

所以问题的主要部分是我应该如何以及何时发送PONG消息来响应PING?我做了我的研究,但仍然无法做到。为什么不能在STDOUT中看到PING消息? (1)循环还不完美,但我认为它是s(012)(012)(012)(012)代码为另一个主题)代码波纹管:

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字符串中一样)。 连接就像一个魅力!

在最后:))

回答

3

所以,我当场就几个问题是:

  1. NICK不正确终止。它应该是\r\n
  2. USER根本没有终止,它应该以\r\n结束。
  3. 当您发送您的ping响应时,您的硬编码大小为512send()不适用于字符串,它可以处理原始数据。所以,你也会在这里传递很多垃圾。您需要根据收到的内容来传递长度。
  4. printf(buf);是不安全的。任何恰巧包含格式化说明符的传入字符串都会导致printf()尝试并解释它们(这称为“格式字符串漏洞”)。应该用printf("%s", buf);替换它们以安全地实现相同的行为。
  5. 一般而言,您的代码假设从IRC收到的消息是nul终止的。他们不是。您应该使用recv()的返回值来了解您收到的数据量。
  6. 您正在使用strlen()来确定缓冲区的大小。该函数计算字符串的长度,而不是缓冲区的大小。您应该使用sizeof运营商。
  7. 我不确定scanf(buf);应该做什么,但它几乎肯定不是你想要的。也许您正在寻找fgets()
  8. 您的recv()呼叫ping发生在buf之后。你怎么知道什么时候会发生,发生多久?好像你应该总是使用相同的缓冲区。