Connecting to IRC via Winsock

I am trying to connect to an IRC server with WinSock. I have an end goal of making a Twitch.tv Chat Bot, but I run into one issue. For some reason I do not receive any replies/prints from the IRC server in my application. I connect to the same IP and use the name PASS and NICK on PuTTy and get a proper IRC connection, yet my C++ Program does not.

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
int main()
{
	WSADATA wsaData;
	int iResult;
	DWORD dwError;
	SOCKET sock;
	struct hostent *remoteHost;
	struct sockaddr_in server;
	char host_name[] = "irc.chat.twitch.tv";
	struct in_addr addr;

	char **pAlias;
	// Initialize Winsock
	iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (iResult != 0) {
		printf("WSAStartup failed: %d\n", iResult);
		return 1;
	}

	printf("Calling gethostbyname with %s\n", host_name);
	remoteHost = gethostbyname(host_name);
	if (!remoteHost)
	{
		printf("Failled to get %s(s) host by name... Error: %d\n", host_name, WSAGetLastError());
		getch();
		exit(1);
	}
	printf("Successfully retrieved host by name...\n");
	int i = 0;
	while (remoteHost->h_addr_list[i] != 0)
	{
		addr.s_addr = *(u_long *) remoteHost->h_addr_list[i++];
		printf("\tIP Address #%d: %s\n", i, inet_ntoa(addr));
	}
	char *ipaddr = inet_ntoa(addr);
	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock == INVALID_SOCKET)
	{
		printf("Socket == Invalid_Socket...\n");
		getch();
		exit(1);
	}

	printf("Gathered All IP Adresses... Using %s\n", ipaddr);
	ZeroMemory(&server, sizeof(&server));
	server.sin_addr.s_addr = inet_addr(ipaddr);
	server.sin_family = AF_INET;
	server.sin_port = htons(6667);
	if (connect(sock, (struct sockaddr *)&server, sizeof(server)) == 0)
	{
		printf("Connected to %s OR %s...\n", host_name, ipaddr);
		Sleep(2000);
		printf("Trying: PASS securityreasons\nNICK ircbot");
		send(sock, "PASS securityreasons\n", strlen("PASS securityreasons") + 1, 0);
		send(sock, "NICK ircbot\n", strlen("ircbot") + 1, 0);
		int mret; char *rbuf;
		while (true)
		{
			ZeroMemory(&rbuf, sizeof(rbuf));
			mret = recv(sock, rbuf, sizeof(rbuf), 0);
			if (!mret)
			{
				printf("Connection broke...\n");
				getch();
				exit(1);
			}
			else
			{
				if(rbuf)
					printf("%s\n", rbuf);
			}
			Sleep(700);
		}
	}
	else
	{
		printf("Failed to connect!\n");
	}
	getch();
	return 0;
}

Output:
[img]http://i.imgur.com/9AyV0Pt.png [/img]
Last edited on
Line 55;

send(sock, "NICK ircbot\n", strlen("ircbot") + 1, 0);

The length is to short.
I change the strlen, but it still doesn't print any responses.
The next problem is line 56: rbuf is an uninitialized pointer. When line 59 is processed the pointer will be set to 0 (sizeof(rbuf) is the size of the pointer). Line 60 will write data to an invalid memory and will most likely crash.

You nee to provide a real buffer like

char rbuf[4096]; // 4k buffer

The size of the buffer depends on the amount of data you're expecting. 4k might be sufficient.

On line 70: This works only when the data is terminated with a 0. I suggest rbuf[mret] = 0 for safety.

Note this:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms740121(v=vs.85).aspx

Particularly this (for windows):
Return value

If no error occurs, recv returns the number of bytes received and the buffer pointed to by the buf parameter will contain this data received. If the connection has been gracefully closed, the return value is zero.

Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
You should be prepared for a SOCKET_ERROR
Thank you @coder777 giving the buffer an actual size fixed it! I as well noticed I never initialized the socket, but I am unsure if that is necessary for IRC so I did anyways.
Topic archived. No new replies allowed.