NetworkProgrammingFAQ

Network Programming FAQ

Why browser does’t render my HTML payload?

  • You payload should be closely follow the Response Header, for example Connection: close\r\n\r\n<html>payload</html>

  • You must first read the request header before you write response data to the socket

How to detect EOF in a socket

Solution 1:

if you know you are working with HTTP protocal

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
char * getheaderline(int socketfd){
char* res = (char*)malloc(sizeof(char) * BS);
char* walk = res;
char c ;
int cot = 0 ;
while(recv(socketfd, &c, sizeof(char), 0) > 0){
if( c == '\r' ){
continue;
}
if (c == '\n' || cot >= BS - 1){
break;
}
*walk++ = c ;
cot++;
}
*walk = '\0';
if (walk == res){
free(res);
res = NULL ;
}
return res ;
}

char * ParseRequest(int socketfd){
char * line ;
while( (line = getheaderline(socketfd)) != NULL ){
printf("%s\n" , line);
free(line);
}
printf("END\n");
return NULL ;
}
Solution 2 (more generic)

Useful!!!

On common way is to use ioctl(..) to query FIONREAD of the socket which will return how much data is available.

1
2
3
4
5
int len = 0;
ioctl(sock, FIONREAD, &len);
if (len > 0) {
len = read(sock, buffer, len);
}

recv, recvfrom, recvmsg - receive a message from a socket
When a stream socket peer has performed an orderly shutdown, the return value will be 0 (the traditional “end-of-file” return).

1
2
3
4
5
6
7
#define BS 1024
char buffer [BS];

int received ;
while ( received = recv(socketfd , (void*)buffer , BS , 0) > 0 ){
printf("received %d bytes : %.*s\n" , received , received , buffer);
}

Each client request must be responsed

Not matter what kind of request it is, GET or POST, the server should send a response back


Heap overflow

Run time error message
1
2
3
free(): invalid next size (normal) in SomeKindOfFunction
//or
malloc: *** error: incorrect checksum for freed object - object was probably modified after being freed
Quote from stackoverflow

It means that you have a memory error. You may be trying to free a pointer that wasn’t allocated by malloc (or delete an object that wasn’t created by new) or you may be trying to free/delete such an object more than once. You may be overflowing a buffer or otherwise writing to memory to which you shouldn’t be writing, causing heap corruption.

Any number of programming errors can cause this problem. You need to use a debugger, get a backtrace, and see what your program is doing when the error occurs. If that fails and you determine you have corrupted the heap at some previous point in time, you may be in for some painful debugging (it may not be too painful if the project is small enough that you can tackle it piece by piece).

Solution:

Write to heap memory with caution !!!

1
2
3
4
5
6
7
8
9
10
11
typedef char byte
char input [large + 1];
byte * buffer = (byte*)malloc( BFsize );

/* Don't do this */
scanf("%s" , input);
strcpy(buffer , input); // potentially overflow

/* Do this */
fgets(input, large , stdin);
strncpy(buffer , input , BFsize);

This kind of bug is hard to detect and painful to debug, since the program will crash in next malloc or free rather than where the overflow happens !!!

For example
1
2
3
4
5
strcpy(buffer , input); // overflow here, the program will continue running without crash
...
...
...
strdup(....) //crash here, giving an illusion that there is a bug in libc function
1
2
3
4
5
6
7
8
9
10
11
while(1){
char clientname [Size];
char clientport [Size];
struct sockaddr clientaddr ;
socklen_t clientlen = sizeof(struct sockaddr);
getnameinfo(&clientaddr , clientlen , clientname , Size , clientport , Size , 0); //crash here
printf("Accept connection from [%s : %s]\n", clientname , clientport);

ReadRequest();
Response(); //overflow here
}