Irc Pong

Hi, I been working on an irc bot but i cant seem to get the PONG command working,
heres my code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//////////Irc.h/////////////
#ifndef __IRC__
#define __IRC__

#include <winsock2.h>
#include <string>

class irc
{
	public:
		void connectToHost(char *server, int port);
		void sendMessage(const char *msg);
		std::string receivedMessage();
	private:
		WSAData wsaData;
		SOCKET connection;
		sockaddr_in service;
		bool connected;
};
#endif
////////////////irc.cpp///////////////
#include "irc.h"
#include <iostream>

void irc::connectToHost(char *server, int port)
{
	LPHOSTENT host;
	if(WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) {
		return;
	}
	host = gethostbyname(server);
	connection = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	service.sin_family = AF_INET;
	service.sin_addr = *((LPIN_ADDR)*host->h_addr_list);
	service.sin_port = htons(port);
	if(connect(connection, (SOCKADDR*)&service, sizeof(service)) == SOCKET_ERROR) {
		std::cout << "Unable to connect. error: " << WSAGetLastError() << std::endl;
		system("pause");
		return;
	}
	std::cout << "Connected!" << std::endl;
	connected = true;
}

void irc::sendMessage(const char *msg)
{
	if(connected) {
		send(connection, msg, sizeof(msg), 0);
	}
}

std::string irc::receivedMessage()
{
	char msg[1024];
	int bytes = recv(connection, msg, sizeof(msg), 0);
	if(bytes > 0) {
		return msg;
	}
	return "";
}
/////////////////client.cpp/////////////////
#include "irc.h"
#include <iostream>
#include <string.h>

using namespace std;

int main()
{
	system("title Irc Client");
	irc* Irc = new irc;
	Irc->connectToHost("multiplay.uk.quakenet.org", 6667);
	Irc->sendMessage("USER F_Fallen * * :F_Fallen\r\n");
	Irc->sendMessage("NICK F_Fallen\r\n");
	while(true) {
		string received = Irc->receivedMessage();
		if(strncmp(received.c_str(), "PING", 4) == 0) {
			char buffer[512];
			for(int i = 0; i < received.length(); i++)
				buffer[i] = received[i];

			buffer[1] = 'O';
			Irc->sendMessage(buffer);
			cout << "Received ping!" << endl;
		} 
		cout << received << endl;
	}
	cout << endl;
	system("pause");
	return 1;
}

thanks
The main problem is that you're treating everything received by recv in one call as a message.
Messages in IRC are line-based. But a call to recv can receive half a line or twenty lines at once, so the current method won't do. Also, you're not null-terminating the char array before calling the string constructor in line 57.
And you should avoid tinkering with char arrays. You can access the individual characters in a string, so you don't need "buffer" at all. Neither do you need strncmp (use substr or find).
Hi, thanks for the answer.
I tried using substr but it fails. Also i dont understand what you exactly mean by "you're not null-terminating the char array before calling the string constructor".
I tried using substr but it fails.

No, it doesn't.
1
2
if(received.length()>=4 && received.substr(0,4)=="PING") {
[...]


Also i dont understand what you exactly mean by "you're not null-terminating the char array before calling the string constructor".

When you return msg in receivedMessage(), you're invoking string (const char*).
You can read what it does here:
http://www.cplusplus.com/reference/string/string/string/
Since you're not setting the null character anywhere, the string constructor will keep walking through msg (and beyond if necessary) until it finds a null character - or until a segmentation fault is triggered.
Hmm, ok. I tried using your method to find the "PING" but it still doesnt work, guess its my way returning char in std::string is wrong.
That's not even the main issue. Read my first post again.
I do understand that, the main problem is that i dont even receive the PING for some reason.
Ah, I see.
It's yet another case of wrong usage of C strings. sizeof(msg) returns the size of a char pointer - that is, 4 or 8.
Fixed version:

1
2
3
4
5
6
void irc::sendMessage(const std::string& msg)
{
	if(connected) {
		send(connection, msg.c_str(), msg.length(), 0);
	}
}
Ok now i can receive the PING.
also why this doesnt work:
1
2
buffer[1] = 'O';
			Irc->sendMessage(buffer);

and what about this too:
 
string buf = "PONG :" + buffer.substr(7) + "\r\n";

;<
edit: nvm i did it myself, thanks.
Last edited on
Topic archived. No new replies allowed.