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 . ..:)