P. 1


|Views: 6|Likes:
Published by kameshdeepakbe

More info:

Published by: kameshdeepakbe on Feb 01, 2011
Copyright:Attribution Non-commercial


Read on Scribd mobile: iPhone, iPad and Android.
download as TXT, PDF, TXT or read online from Scribd
See more
See less





BASIC C Socket Programming In Unix For Newbies <=================================================> Written by: BracaMan E-mail : BracaMan@clix.

pt ICQ : 41476410 URL : http://www.BracaMan.net For more tutorials: http://code.box.sk http://blacksun.box.sk For comments, errors or just to say hello: <BracaMan@clix.pt>

CONTENTS ======================================= 1. 2. 3. 4. 5. 6. Introduction Different types of Internet Sockets Structures Conversions IP Addresses Important Functions 6.1. socket() 6.2. bind() 6.3. connect() 6.4. listen() 6.5. accept() 6.6. send() 6.7. recv() 6.8. sendto() 6.9. recvfrom() 6.10. close() 6.11. shutdown() 6.12. gethostname() 7. Some words about DNS 8. A Stream Server Example 9. A Stream Client Example 10. Last Words 11. Copyright

1. INTRODUCTION ======================================= Are you trying to learn c socket programming? Or do you think that it's hard stu ff? Well, then you must read this basic tutorial to get basic ideas and concepts and to start to work with sockets. Don't expect to be a "socket programming master" after rea

a sock et is a way to talk to other computer. For the moment. A file descriptor is just an integer associated with an op en file and it can be a network connection. In a very simple way.you build a packet with the destination infor mation and send it out. You'll learn it in the next sections.B. they use TCP ("Transmission Control Protocol") . STRUCTURES ======================================= The purpose of this section is not to teach you structures but to tell you how a re they used in C socket programming. A lot more could be explained here about this two kind of sockets. You'll only be that if you practice and read a lot. Datagram Sockets . 2. they're connec tionless because you don't need to have an open connection as in Stream Sockets . About the different types of internet sockets.ding this tutorial. DIFFERENT TYPES OF INTERNET SOCKETS ======================================= In the first place I must explain what a socket is.this p rotocol assures the items' order.Stream Sockets (SOCK_STREAM) and Datagram Sockets (SOCK_DGRAM).C" . 3. Understanding what a socket is and this two types of internet sockets is a good start. if you send through the stream sock et three items "A. "And what are the differences between this two types?" you may ask. B."A. my advice i s to read a C Tutorial and learn it. every I/O actions are done by writing o r reading to a file descriptor.they use UDP ("User Datagram Protocol").they're error free. it's a way to talk to other compu ters using standard Unix file descriptors. it contains other data types. which are grouped t . In Unix. there are many types but I'll jus t describe two of them . but you need to learn how to "work" with them. let's just say that a structure is a data type that is an aggregate. but I think t his is enough to get the basic concept of socket. a terminal.C". Here's the a nswer: Stream Sockets . or something else. If you don't know what a structure is. that is. they will arrive in the same order . To be more precise.

ogether into a single user-defined type. In the Stream Client Exa mple. Here it is: . Finally. /* /* /* /* Address family */ Port */ Internet Address */ Same size as struct sockadd Note: sin_zero is set to all zeros with memset() or bzero() (See examples bellow ).) Here's the structure anyway: struct in_addr { unsigned long s_addr. The first structure is struct sockaddr that holds socket information. struct sockaddr{ unsigned short sa_family.sin_addr = (. sin_zero[8]. /* address family */ char sa_data[14]. sin_port. I think it's better talk about struct hostent. /* 14 bytes of protocol address */ }. you can see that I use this structure. struct sockaddr_in { short int unsigned short int struct in_addr unsigned char r */ }. But. }. when I declare for example "client" to be of type sockaddr_in then I do client.. sin_family. As you can see in both examples bellow (Stream Client and Server Client) . This structure is used to get remote host informa tion. Structures are used in socket programming to hold information about the address. there's another structure (struct sockaddr_in) that help you to reference t o the socket's elements. sin_addr. The next structure is not very used but it is defined as an union..

CONVERSIONS ======================================= There are two types of byte ordering: most significant byte and least significan t byte. W hat would you do? There's a function called htonl() that would convert it =) The following fun ctions are used to convert : htons() htonl() ntohs() ntohl() -> -> -> -> "Host to "Host to "Network "Network Network Network to Host to Host Short" Long" Short" Long" You must be thinking why do you need this. /* /* /* /* /* Official name of host. char **h_aliases. it will be easier for you understanding th em.struct hostent { char *h_name. IP ADRESSES ======================================= In C. for backward compatibility. */ */ }. this structures will confuse you a lot. int h_addrtype. To see how you can use them check the examples (section 8 and 9). is that sin_addr and sin_port (from struct sockaddr_in) must be in Network Byte Order (you'll see in the examples the functions described here to convert a nd you'll start to understand it). char **h_addr_list. but after you start to write some lines. This former is called "Network Byte Order" and some machines store their numbers internally in Network Byte Order. and after seeing the examples. when you finish reading this do cument. This structure is defined in header file netdb. #define h_addr h_addr_list[0] /* Address. there are some functions that will help you manipulating IP addresses. 5. int h_length. */ List of addresses from name server. */ Alias list. We' ll talk about . */ Host address type. */ Length of address. In the beginning.h. 4. it will all seems easier =) All you need is to read and a lot of practice =) An important thing. Well. Imagine you want to convert a long from Host Byte Order to Network Byte Order. There are two types you can convert: short and long.

inet_addr() and inet_ntoa() functions.sin_addr.. An example: (.12").so you don 't need to call htonl().) char *IP...1.int type. 6. An example: (. Maybe I'll put them in a future version o f this document =) To see examples of these functions.. Besides the functions mentioned in this document.h> #include <sys/socket. (. inet_addr() converts an IP address into an unsigned long. the header files you must include to call it. socket() ============= #include <sys/types. and little comments..65.) dest..sin_addr).) /*Remember that this is if you've a struct dest of type sockaddr_in*/ inet_ntoa() converts string IP addresses to long. Let's see the arguments: domain net protocols) or "AF_UNIX" if you want to create sockets for insid -> you can set "AF_INET" (set AF_INET to use ARPA inter . there are more. ip=inet_ntoa(dest.h> int socket(int domain. you can check the stream client and stream server source code (Sections 8 and 9) 6...36. printf("Address is: %s\n".ip).) Remember that inet_addr() returns the address in Network Byte Order . but I decided to put only these ones here.s_addr = inet_addr("195.int protocol). (. IMPORTANT FUNCTIONS ======================================= In this section I'll put the function' syntax.

s_addr = INADDR_ANY. 6.h> #include <sys/socket. struct sockaddr *my_addr. Let's see the arguments: fd -> is the socket file descriptor returned by socket() call my_addr -> is a pointer to struct sockaddr addrlen -> set it to sizeof(struct sockaddr) bind() is used when you care about your local port (usually when you use listen() ) and its function is to associate a socket with a port (on your machine). bind() =========== #include <sys/types.int addrlen). ndom port*/ server.sin_port = 0. -> here you put the kind of socket you want (Stream or . 6. but don't think that th ere are just type Datagram) If you want Stream Socket the type must be SOCK_ST REAM If you want Datagram Socket the type must be SOCK_ DGRAM protocol -> you can just set protocol to 0 socket() gives you a socket descriptor that you can use in later system calls or it gives you -1 on error (this is usefull for error checking routines).sin_addr. /* puts server's IP automa tically */ An important aspect about ports and bind() is that all ports bellow 1024 are reserved. You can put your IP address and your port automatically: server.h> /* bind() will choose a ra those.2.h> #include <sys/socket. Those two are the most used.h> int bind(int fd. You can set a port above 1024 and bellow 65535 (unless the ones being u sed by other programs).e comunication. There are more I just don't mention them.3. It returns -1 on error. connect() ============== #include <sys/types.

int connect(int fd. Let's see the arguments: fd -> is the socket file descriptor returned by listen() call addr -> is a pointer to struct sockaddr_in where you can dete rmine which host is calling you from which port socket() bind() listen() accept() /* In the next section I'll explain how to use accep . 4. you must ca ll bind() or you'll be listening on a random port =) After calling listen() you mu st call accept() in order to accept incoming connection. this is. listen() ============= #include <sys/types. Resuming. Before calling listen(). void *addr.5. Let's see the arguments: fd -> is the socket file descriptor returned by socket() call backlog -> is the number of allowed connections listen() is used if you're waiting for incoming connections. 2. 3. the sequence of system calls is: 1. if you want someone to connect to your machine. int *addrlen). 6. t() */ As all functions above described. int addrlen). struct sockaddr *serv_addr.4. It retu rns -1 on error.h> #include <sys/socket. 6. accept() ============= #include <sys/socket. Let's see the arguments: fd -> is the socket file descriptor returned by socket() call serv_addr -> is a pointer to struct sockaddr that contains desti nation IP addrlen address and port -> set it to sizeof(struct sockaddr) connect() is used to connect to an IP address on a defined port.h> int accept(int fd.int backlog).h> int listen(int fd. listen() returns -1 on error.

.(struct sockaddr *)&client.) sin_size=sizeof(struct sockaddr_in). unsigned int flags). send() returns the number of bytes sent out and it will return -1 on err or. I'll give you a little example of accept() use because it's a litt le different from other functions.int len. } (.int flags). exit(-1).. If you want to send data over UNCONNECTED datagram sockets you must use sendto(). 6.&sin_size))==-1){ /* c alls accept() */ printf("accept() error\n"). 6. if ((fd2 = accept(fd. int len. It's very simple to understand: you just get a connection if you accept =) Next. Let's see the arguments: fd -> msg len flags is the socket descriptor where you want to send data to -> is a pointer to the data you want to send -> is the length of the data you want to send (in bytes) -> set it to 0 This function is used to send data over stream sockets or CONNECTED data gram sockets. fd2 will be used for add send() and recv() calls. void *buf.addrlen -> set it to sizeof(struct sockaddr_in) before its addre ss is passed to accept() When someone is trying to connect to your computer. Let's see the arguments: .const void *msg.. send() =========== int send(int fd.6.) From now on..7. you must use accept( ) to get the connection. (. recv() =========== int recv(int fd.

6. recv() returns the number of bytes read into the buffer and it'll return -1 on error. unsigned int flags struct sockaddr *from. const struct sockaddr *to. int tolen). Let's see the arguments: fd buf len flags from fromlen d to sizeof(struct sockaddr) recvfrom() returns the number of bytes received and it'll return -1 on e rror. If you want to send data over UNCONNECTED da tagram sockets you must use recvfrom(). sendto() ============= int sendto(int fd. this function is used to send data over st ream sockets or CONNECTED datagram sockets.8. sendto() is just like send().void *buf.const void *msg. 6. It has only two more argum ents : "to" and "tolen" =) sendto() is used for UNCONNECTED datagram sockets and it returns the num ber of bytes sent out and it will return -1 on error. int len. recvfrom() =============== int recvfrom(int fd. -> -> -> -> -> -> the same as recv() the same as recv() the same as recv() the same as recv() is a pointer to struct sockaddr is a pointer to a local int that should be initialise .9. int len. Let's see the arguments: fd -> msg len flags to tolen the -> -> -> -> -> same as send() the same as send() the same as send() the same as send() is a pointer to struct sockaddr set it to sizeof(struct sockaddr) As you can see.fd -> buf len flags is the socket descriptor to read from -> is the buffer to read the information into -> is the maximum length of the buffer -> set it to 0 As I said above about send(). unsigned int flags. int *fromlen).

shutdown() returns 0 on success and -1 on error. int how). For example. because functions we saw above (like bind() and connect()) wo rk with IP . 6. close() ============= close(fd). it's used to get IP addresses. it's the same thing as close(). Let's see the arguments: hostname -> is a pointer to an array that contains hostname size -> length of the hostname array (in bytes) gethostname() is used to get the name of the local machine. Let's see the arguments: fd how -> is the socket file descriptor you want to shutdown -> you put one of those numbers: 0 -> receives disallowed 1 -> sends disallowed 2 -> sends and receives disallowed When how is set to 2.13 .10.37.ptlink.h> int gethostname(char *hostname. DNS stands for "Domain Name Service" and basically.11. This is important. 6.net and through DNS I'll get 212. If yo u call close(). close() is used to close the connection on your socket descriptor. SOME WORDS ABOUT DNS ======================================= I created this section.12.6. gethostname() =================== #include <unistd.13. it won't be no more writes or reads and if someone tries to read/write w ill receive an error. because I think you should know what DNS is. shutdown() ================ int shutdown(int fd. I need to know the IP address of queima. 7. size_t size).

/* prin ts IP address */ } /* <---.he->h_name). /* prints the hostname */ printf("IP Address: %s\n".h> int main(int argc.h> /* This is the header file needed for gethostbyname() */ <sys/types.h> /* These are the usual header files */ #define PORT 3550 #define BACKLOG 2 main() { /* Port that will be opened */ /* Number of allowed connections */ .ptlink.h> <sys/types.h> <sys/socket.net IP address on c. exit(-1).addresses. I made a little ex ample: /* <---. exit(-1). } if ((he=gethostbyname(argv[1]))==NULL){ printf("gethostbyname() error\n"). char *argv[]) { struct hostent *he.SOURCE CODE ENDS HERE ----> */ 8.h> <netinet/in. } printf("Hostname : %s\n".argv[0]). I'll show you a nice example of a stream server. The source cod e is all commented so that you ain't no possible doubts =) Let's start: /* <---. if (argc!=2){ printf("Usage: %s <hostname>\n".h> <sys/socket. To see you how you can get queima.SOURCE CODE STARTS HERE ----> */ #include #include #include #include <stdio.inet_ntoa(*((struct in_addr *)he->h_addr))). A STREAM SERVER EXAMPLE ======================================= In this section.SOURCE CODE STARTS HERE ----> */ #include #include #include #include #include <stdio.h> <netdb.h> <netinet/in.

/* server's address information */ struct sockaddr_in client.SOURCE CODE ENDS HERE ----> */ 9. /* Remember htons() from "Conversions" sectio n? =) */ server.sizeof(struct sockaddr))==-1){ /* calls b ind() */ printf("bind() error\n").BACKLOG) == -1){ /* calls listen() */ printf("listen() error\n"). /* file descriptors */ struct sockaddr_in server.h> . exit(-1).&sin_size))==-1){ /* calls acc ept() */ printf("accept() error\n"). if ((fd=socket(AF_INET. /* INADDR_ANY puts your IP address autom atically */ bzero(&(server. /* send to the client welcome messag e */ close(fd2). } printf("You got a connection from %s\n".8)."Welcome to my server.sin_family = AF_INET.sin_port = htons(PORT). } while(1){ sin_size=sizeof(struct sockaddr_in). /* print s client's IP */ send(fd2. /* client's address information */ int sin_size. server. exit(-1).sin_addr.int fd.sin_zero).sin_addr) ).\n". /* close fd2 */ } } /* <---. if ((fd2 = accept(fd. SOCK_STREAM. /* zero the rest of the structure */ if(bind(fd.22. } if(listen(fd. 0)) == -1 ){ /* calls socket() */ printf("socket() error\n"). A STREAM CLIENT EXAMPLE ======================================= /* <---.(struct sockaddr*)&server. fd2.(struct sockaddr *)&client.SOURCE CODE STARTS HERE ----> */ #include <stdio.inet_ntoa(client. exit(-1). exit(-1). } server.s_addr = INADDR_ANY.0).

SOURCE CODE ENDS HERE ----> */ /* close fd =) */ .sizeof(struct sockaddr))==-1){ /* ca lls connect() */ printf("connect() error\n"). SOCK_STREAM.h> /* netbd. /* htons() is needed again */ server. exit(-1). exit(-1).h> <netinet/in.MAXDATASIZE. } if ((he=gethostbyname(argv[1]))==NULL){ printf("gethostbyname() error\n"). server.sin_port = htons(PORT). } server.buf. } buf[numbytes]='\0'.sin_family = AF_INET.sin_zero). /* it prints server's welcome message =) */ close(fd). printf("Server Message: %s\n". /* files descriptors */ char buf[MAXDATASIZE]. } /* <---.argv[0]). /* server's address information */ if (argc !=2) { /* this is used because our program will need one argument (IP) */ printf("Usage: %s <IP Address>\n". exit(-1). } if ((numbytes=recv(fd. } /* calls gethostbyname() */ if ((fd=socket(AF_INET.h> <netdb.0)) == -1){ /* calls recv() */ printf("recv() error\n").#include #include #include #include <sys/types. if(connect(fd.h is needed for struct hostent =) */ /* Open Port on Remote Host */ /* Max number of bytes of data */ #define PORT 3550 #define MAXDATASIZE 100 int main(int argc.buf). /* structure that will get information about remot e host */ struct sockaddr_in server. (struct sockaddr *)&server. numbytes.sin_addr = *((struct in_addr *)he->h_addr). 0))==-1){ /* calls socket() */ printf("socket() error\n").8). /* buf will store received text */ struct hostent *he. exit(-1). exit(-1).h> <sys/socket. char *argv[]) { int fd. /*he->h_addr passes "*he"' s info to "h_addr" */ bzero(&(server.

pt> SPECIAL THANKS TO: Ghost_Rider (my good old mate). Please email me if you detect any error =) But you must understand that this is the first version of this document. However. LAST WORDS ======================================= As I'm just a simple human. it's almost certain that there are some errors on th is document. as long yo u don't change any name or URL. I can be sure that source code presented in this documen t works fine. it 's natural not to be very complete (as matter of fact I think it is ) and it's also very natura l to have stupid errors. so . please email me at <BracaMan @clix. If you want to change something. and then claim that this tutorial is yours. You can distribute this tutorial freely. COPYRIGHT ======================================= All copyrights are reserved. Raven (for letting me write t his tutorial) and all my friends =) 11.10. If you need help concerning this subject you can email me at <BracaMan@clix. . When I say errors I mean English errors (because my language is not the English) but also technical errors. or add another lines. You can't change a line or two.pt>.

You're Reading a Free Preview

/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->