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 : ))
So, a few issues I spot right away are:
NICK
is not properly terminated. It should be\r\n
.USER
is not terminated at all, it should end with\r\n
.- 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. printf(buf);
is not safe. Any incoming string that happens to contain formatting specifiers will causeprintf()
to try and interpret them (this is known as a "format string vulnerability"). They should be replaced withprintf("%s", buf);
to achieve the same behavior in a safe way.- 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. - 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 thesizeof
operator instead. - I'm not sure what
scanf(buf);
is supposed to do, but it's almost certainly not what you wanted. Maybe you were looking forfgets()
? - Your
recv()
call for ping happens right after the one forbuf
. 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.
来源:https://stackoverflow.com/questions/10482249/how-to-connect-to-irc-server-parse-irc-msgs-ping-pong-handling-in-c-language