Академический Документы
Профессиональный Документы
Культура Документы
http://shoe.bocks.com/net/
Contents
Introduction Creating a socket Binding a socket to a port Listening for connections Accepting a connection Closing connections Sending data to a connection Receiving data from a connection Setting socket options Handling more than one connection Converting a hostname into a network address Establishing an outgoing connection Changes made to the tutorial Download the entire tutorial (.tar.gz) Download the entire tutorial (.zip) View the files out of my network library Download my network library Link to the glossary
Copyright 1996-2013 Simon Amor
Introduction
In this tutorial, I will attempt to explain the use and syntax of some of the basic UNIX networking functions in C. If you want to know more about Windows Sockets programming, I'm afraid the WinSock resources at StarDust have disappeared now - any pointers to similar pages would be appreciated! You might also want to check out the Internet programming crash course. You could also visit Networking ABC Everything Networking, from 2 computer home networking to XP networking. There are some example programs which I will explain how to write from the beginning. If you would like to know more about a function, you might have on-line manual pages (use 'man function') or your system administrators may be able to provide manuals. You can view or download the source code but I cannot guarantee that it will work on all systems so if you find any code that doesn't work, please email me with details of your system (Operating
1 sur 9
14/07/2013 19:48
http://shoe.bocks.com/net/
System, Architecture etc) and what doesn't work and I'll see if I can fix it. I would also appreciate email telling me if it DOES work on your system (or if you managed to modify parts and get it working), if you could email the alterations to me, I can then incorporate your modifications into the source code. Some platforms that have been tested:
Linux, kernel 2.2.x, gcc2 Linux, kernel 2.4.x, gcc3 Mac OSX 10.3 - references to malloc.h need to be changed to sys/malloc.h and as well as 'ar', you also need to run 'ranlib' on the library file libnet.a (built from the network library source) HPUX - need to add -lsocket when linking executable as mentioned below.
With some versions of UNIX, the example programs will not link, complaining about things such as undefined symbols bind, accept, listen and socket. Such errors will probably look like this: Undefined first referenced symbol in file socket /var/tmp/ccLkjMcu.o accept /var/tmp/ccLkjMcu.o bind /var/tmp/ccLkjMcu.o listen /var/tmp/ccLkjMcu.o ld: fatal: Symbol referencing errors. No output written to a.out This generally indicates that you should link in an additional library by adding -lsocket to the cc line. For example: cc -o netapp netapp.c -lsocket This tutorial assumes you know how to program in C. If you find this tutorial of any interest whatsoever, please contact me and let me know. It's nowhere near complete as yet, but mail me anyway even if it's only to say "Hey! get that tutorial finished" :-) Back to contents
Creating a socket
The first thing to do is to create a socket which you can then manipulate in many ways. To create a socket, you can use the socket() function. Includes: #include <sys/types.h> #include <sys/socket.h> Syntax: int socket(int af, int type, int protocol); C source: int socket_desc; socket_desc=socket(AF_INET,SOCK_STREAM,0); if (socket_desc==-1) perror("Create socket"); socket() returns a socket descriptor which can be used in other network commands. This will create a socket which uses DARPA Internet addresses, and the method of connection is a byte stream which is similar to a pipe. An alternative to byte streams is a datagram but this tutorial does not cover them.
2 sur 9
14/07/2013 19:48
http://shoe.bocks.com/net/
With servers, the first socket created is often known as a " master socket". Before the socket can send or receive data, it must be connected to another socket. If acting as a master socket, it must be bound to a port number so that clients can know where to "find" the socket and connect to it. If successful, socket() returns a valid socket descriptor; otherwise it returns -1 and sets errno to indicate the error. perror() or strerror() can be used to turn the errno value into a human readable string. Back to contents
3 sur 9
14/07/2013 19:48
http://shoe.bocks.com/net/
Includes: #include <sys/socket.h> Syntax: int listen(int s, int backlog); C source: listen(socket_desc,3); the above line specifies that there can be up to 3 connections pending. If a connection request arrives when there are already 3 connections pending, the client receives a timeout error. listen() applies only to unconnected sockets of type SOCK_STREAM. If the socket has not been bound to a local port before listen() is invoked, the system automatically binds a local port for the socket to listen on. If successful, listen() returns 0; otherwise it returns -1 and sets errno to indicate the error. Back to contents
Accepting a connection
To actually tell the server to accept a connection, you have to use the function accept() Includes: #include <sys/socket.h> Syntax: int accept(int s, struct sockaddr *addr, int *addrlen); C source: int addrlen; struct sockaddr_in address; addrlen = sizeof(struct sockaddr_in); new_socket = accept(socket_desc, (struct sockaddr *)&address, &addrlen); if (new_socket<0) perror("Accept connection"); accept() is used with connection based sockets such as streams. The parameters are the socket descriptor of the master socket followed by a sockaddr_in structure and the size of the structure. If successful, accept() returns a positive integer which is the socket descriptor for the accepted socket. If an error occurs, -1 is returned and errno is set to indicate the cause. There is some example source code in the directory, the program to compile is called `accept' While it is running, type: telnet localhost 7000 and you should get Trying... Connected to localhost. Escape character is '^]'. and then 10 seconds later, it should close the connection. Once again, if the connection is refused immediately, there is probably a problem with the server. Back to contents
4 sur 9
14/07/2013 19:48
http://shoe.bocks.com/net/
Closing connections
Probably one of the easiest things to do with a socket, is close it. This is done using close() Includes: #include <unistd.h> Syntax: int close(int sockdes); C source: close(new_socket); close() closes the socket descriptor indicated by sockdes. Upon successful completion, close() returns a value of 0; otherwise, it returns -1 and sets errno to indicate the error. Back to contents
5 sur 9
14/07/2013 19:48
http://shoe.bocks.com/net/
sets errno to indicate a locally-detected error. The `accept' program is modified to send a welcome message to the connection before it closes the socket. To see how this is done, have a look at the source code for the program `send'. Back to contents
setsockopt(socket_desc,SOL_SOCKET,SO_REUSEADDR, (char *)&opt,sizeof(opt)); SOL_SOCKET specifies the option is a `socket level' option, these are defined in <sys/socket.h>
6 sur 9
14/07/2013 19:48
http://shoe.bocks.com/net/
The socket is identified by the socket descriptor s. The option SO_REUSEADDR is only valid for AF_INET sockets. There are two kinds of options: boolean and non-boolean. Boolean options are either set or not set and also can use optval and optlen to pass information. Non-boolean options always use optval and optlen to pass information. Back to contents
7 sur 9
14/07/2013 19:48
http://shoe.bocks.com/net/
Syntax: struct hostent *gethostbyname(const char *name); C source: struct hostent *hent; hent = gethostbyname("www.foobar.net"); A hostent structure: struct hostent { char *h_name; char **h_aliases; int h_addrtype; int h_length; char **h_addr_list; } /* /* /* /* /* official name of host */ alias list */ host address type */ length of address */ list of addresses */
Some of the network functions require a structure containing the network address and sometimes the port number to connect to or from. The easiest way to convert a hostname to a network address is to use the gethostbyname() function. gethostbyname() returns a structure of type hostent - this structure contains the name of the host, an array of alternative names and also an array of network addresses (in network byte order). Back to contents
Create the socket using socket(), convert the hostname to an IP address using gethostbyname() and then issue the connect() call passing the relevant structures containing the IP address and port to connect to. struct hostent *he; struct sockaddr_in server; int sockfd; /* resolve localhost to an IP (should be 127.0.0.1) */ if ((he = gethostbyname("localhost")) == NULL) { puts("error resolving hostname.."); exit(1); } /* * copy the network address part of the structure to the * sockaddr_in structure which is passed to connect() */ memcpy(&server.sin_addr, he->h_addr_list[0], he->h_length); server.sin_family = AF_INET; server.sin_port = htons(7000); /* connect */ if (connect(sockfd, (struct sockaddr *)&server, sizeof(server))) { puts("error connecting..");
8 sur 9
14/07/2013 19:48
http://shoe.bocks.com/net/
exit(1); } Using connect() ... more to come when/if I get around to it. Back to contents Changes: 7th May 2013 : Added link to Serbo-Croatian translation at http://science.webhostinggeeks.com /uvod-u-c 5th December 2012 : Corrected missing bracket in connect section as pointed out by Nicolai Raaschou. 19th September 2008 : Corrected socket used for send(), recv(), close() from socket_desc to new_socket as pointed out by Mark Pulver. 26th May 2006 : Added link to networkingabc.com 23rd June 2004 : Added information about getting it to work on Mac OSX 10.3 (due to a query regarding this from Nicolas). Tweaked the source to netlib slightly - main bugfix was to correct filenames in the Makefile. 15th November 2003 : Removed link to StarDust WinSock resources as this site has disappeared. 20th February 2003 : In Creating a socket, fixed comparison of socket() return value to -1 to indicate error instead of 0 (thanks to Vince for pointing this out). 16th September 2002 : Converted to be XHTML 1.0 Strict compliant and use CSS properly. Also added link to glossary page. 14th September 2002 : Added url to Internet programming crash course (thanks to Kelly Mandrake). 20th March 2001 : Improved navigation 2nd December 2000 : Updated locations and email addresses 29th May 1999 : Added information about -lsocket. 4th May 1998 : Added an extra include for socket() as per the man page. 13th April 1998 : Added links to downloadable source for netlib. 18th March 1998 : Added a link to downloadable archive for offline reading. 9th October 1997 : Corrected he->h_addr[0] to he->h_addr_list[0] under the connect section
9 sur 9
14/07/2013 19:48