Friday, November 25, 2011

TCP server

Today we will discuss about tcp server which will be serving more clients at one time . Usually we do use  simple echo server one client at a time . In Unix operating systems we can easily creates multiple client handling server even-though so many advanced options out there. In fork system call will help us to  achieve this. check out the following code


/*
 * server.cpp
 *
 *  Created on: Nov 26, 2011
 *      Author: srijeyanthan
 */
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
void str_echo(int sockfd);

using namespace std;
int main(int argc, char **argv) {
pid_t childid;
sockaddr_in serveraddr, clientaddr;
socklen_t clilen;
int listnfd, clientfd;

listnfd = socket(AF_INET, SOCK_STREAM, 0);


memset(&serveraddr, 0, sizeof(serveraddr));

serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(9999);
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);

bind(listnfd, (struct sockaddr*) &serveraddr, sizeof(serveraddr));

listen(listnfd, 7);


for (;;) {
clilen = sizeof(clientaddr);
cout <<"intial client len ::"<<clilen<<endl;
clientfd = accept(listnfd, (struct sockaddr*) &clientaddr, &clilen);



if ((childid = fork()) == 0) {
close(listnfd);
str_echo(clientfd);
cout <<"echoed successfully.."<<endl;
exit(0);

}
close(clientfd);

}

return 0;
}

void str_echo(int sockfd) {
ssize_t n;
char buf[1024];
again: while ((n = read(sockfd, buf, 1024)) > 0)
write(sockfd, buf, n);
if (n < 0 && errno == EINTR)
goto again;
else if (n < 0)
cout<<"str_echo: read error"<<endl;
}


you guys might be knowing  common steps of  socket creation binding and listing . accept system call is blocking , So it will return client connection ID when client is successfully handshake . The above code has explained , whenever new client arrives we are spawning new client and client specific process will be handled by that particular process .  Main drawback of this method would be every client we have to spawn new process which will end up with so many resource consuming in kernel level . For small number of clients we can use this method very efficiently. 

Tuesday, November 8, 2011

Type casting secrets


Hello everyone , I would like to share some common type casting secrets things with you. Most of you guys having problem with C/C++ type casting . I hope this post would help you guys to clear your knowledge .
consider the following code
int ival =257;
char   zVal = (char)iVal;

The output would be 1; How come this value . Let me explain .
  binary representation of iVal in memory would be like this  - 00000000 00000000 00000001 00000001
since char consumes 1 byte of memory , first 8 bits will be extracted from iVal . So output is 00000001 =1
sometimes you will get an different result because of machine's architecture . (my one is big endian)

The above example could be shown in following pointer method .
int *ip = new int(257);
char *zVal = (char*)ip;
when you print zVal  (cout <<"Output:"<<(int)*zVal<<endl;) you will get same value that you have received previously . So what is different between both (char*)ip and (char)iVal .  Some might thought when we do a pointer casting 4 bytes memory will be extracted ..:) Actually that is wrong .  Pointer casting converts data types in to pointer .

we will dig further in casting .
struct A
{
  int a ;
  int b ;
};
 struct B
{
  int c;
};

int main()
{
   A aa;
aa.a =100;
aa.b = 200;

B bb = (B)aa;    // Error . this casting is not allowed in C/C++

B *bb = (B*)&aa   // This is fine .

A *pa = new A;
pa->a =100;
pa->b= 200;

B *pb = (B*)pa;  // this is will work fine .
}


So we can cast both way in C/C++ which means we can cast any data type .


When you declare STRUCT_A it is declared into memory:
|A|A|?|?|
Since it contains two integer it takes up one block of memory(hypothetically)

When you declare STRUCT_B it is declared into memory:
|B|?|?|?|
With one integers it takes up two blocks.

If you do (STRUCT_A)struct_b;
only the first two block of B is going to be read since STRUCT_A only takes two block of memory.

if you (STRUCT_B)struct_a;
the int in STRUCT_A will be read, along with who know what in the next block of memory since STRUCT_B calls for one blocks of memory.

In C++ we can find more about casting . We will discuss about that later . ..:)



Thursday, October 13, 2011

C++ memory management


Hello everyone ,
As this is my first , I would like share something with you guys . I have been inspired by my friends who have been sharing their  thoughts and other intersting stuffs via blogs since my university period. I thought of stating a techinal related blog soon after my graduation, unfortunely I couldnt achive that so far . Today, that dream  comes to an end and I have started to writing my first post here. Since , I like to share techical stuffs with you guys, I’ve  grabed a topic call memory mangement in C++.

Coming days I will explain more advance and comprehensive memory management methods in C/C++,  how low level memory allocation/deallocation works  and performance optimiztion using memory management

Memory  allocation in C and C++ is somwhat different accoring to their standards and specifications. We will talk about that in detail later . First come to the point ,  We often make mistake in double pointer creation and deletion in C/C++.  Fist we will look in to how C++ double pointer allocation and deallocation works .
Consider the following code:

Code:
int ia = 3;

int **ppA = new int*[ia];

for(int i=0; i < ia; ++i)
{
  ppA[i] = new int[i+1];
}

delete [] ppA;

The above code snippet will generate memory leaks while we are running our program.  Why? Because we are not freeing all the allocated memory. Because ppA is an array of pointers, with each of it's elements pointing to a separate memory block, so we have to free these block before freeing the array that holds the pointers.

We are actually allocating 4 + 8 + 12 = 24 bytes in three different memory blocks on the heap, plus the memory necessary to hold the pointers to those 24 bytes.

When you do this:

Code:
delete [] pAA;


we aree only freeing this memory holding the 3 pointers, not the memory they point to. So this will lead to a memory leak . 

The above diagram dipicts that manipulation of internal memory . So in order to avoid the memory leaks we must free those blocks first:

Code:
for(i=0; i < ia; i++)
{
  delete [] ppA[i];
}

delete [] pAA;

Now everything will work fine