2012-05-07 92 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之後。你怎麼知道什麼時候會發生,發生多久?好像你應該總是使用相同的緩衝區。