How to connect to IRC server/ parse IRC MSGs / PIN

2020-08-01 14:46发布

问题:

am writing IRC client in C lang. and encountered some problems while connecting to serwer. I get the following when i run the program:

OUTPUT

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:: - means that is passed by a program for now, so i dont have to type it many times.

btw. am connecting to irc.gbatemp.net:5190 (no password required as far as am concerned)

after providing necessary data 10-20 seconds break happens (i specified in the OUTPUT part) and than ERROR temp.net part follows ad infinitum (i marked it with dots)

So the main part of the problem is how and when should i send PONG message in respons to PING ? i did my research but still cant make it. Why cant i see PING message in the STDOUT ?

am providing the code responsible for the output and PINGPONG part bellow (commented) (main problem for now is PING PONG as Error states PING TIMEOUT) propably while(1) loop is not perfect yet, but i suppose it s subject for another topic) code bellow:

    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;
                    }
                }
//--------------------------------------------------------------------------

Ok. I will leave the question for others in future and provide an answer. It was trival.

I just added \n\r at the end of USER variable (just like in NICK string). Connected like a charm !!

at last : ))

回答1:

So, a few issues I spot right away are:

  1. NICK is not properly terminated. It should be \r\n.
  2. USER is not terminated at all, it should end with \r\n.
  3. When you send your ping response, you have a hard coded size of 512. send() doesn't work on strings, it works on raw data. So, you'll be passing along lots of garbage here too. You need to pass the length based on what you received.
  4. printf(buf); is not safe. Any incoming string that happens to contain formatting specifiers will cause printf() to try and interpret them (this is known as a "format string vulnerability"). They should be replaced with printf("%s", buf); to achieve the same behavior in a safe way.
  5. In general your code assumes that the messages received from the IRC are nul-terminated. They are not. You should be using the return value of recv() to know how much data you received.
  6. You are using strlen() to determine the size of your buffer. This function calculates the length of a string, not the size of your buffer. You should be using the sizeof operator instead.
  7. I'm not sure what scanf(buf); is supposed to do, but it's almost certainly not what you wanted. Maybe you were looking for fgets()?
  8. Your recv() call for ping happens right after the one for buf. How do you know which will happen when and how long they will be? Seems like you should always be working with the same buffer.


标签: c sockets ping irc