network programming
DESCRIPTION
Network Programming. UNIX Internet Socket API. Everything in Unix is a File. When Unix programs do any sort of I/O, they do it by reading or writing to a file descriptor. A file descriptor is simply an integer associated with an open file. The file can be: Network connection. Pipes. - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/1.jpg)
Network Programming Network Programming
UNIX Internet Socket API
![Page 2: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/2.jpg)
Everything in Unix is a FileEverything in Unix is a File
• When Unix programs do any sort of I/O, they do it by reading or writing to a file descriptor.
• A file descriptor is simply an integer associated with an open file.
• The file can be:
– Network connection.
– Pipes.
– A real file on-the-disk.
– Just about anything else.
![Page 3: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/3.jpg)
Two Types of Network Two Types of Network SocketsSockets
• Connection Oriented Sockets
• Datagram Sockets
![Page 4: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/4.jpg)
Connection Oriented Connection Oriented SocketsSockets
• Stream sockets are reliable two-way connected communication streams, both FIFO and Error free.
• The “Transmission Control Protocol", otherwise known as "TCP“.
– TCP makes sure your data arrives sequentially and error-free.
• Used by Applications/Protocols:
– Telnet
– HTTP
– FTP
![Page 5: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/5.jpg)
Datagram sockets Datagram sockets
• Connectionless? You don't have to maintain an open connection as you do with stream sockets. You just build a packet and send it out.
• Whenever you send a datagram:
– it may arrive.
– It may arrive out of order or duplicate.
– If it arrives, the data within the packet will be error-free.
• The “User Datagram Protocol ", otherwise knownas “UDP“.
• What is it good for?
![Page 6: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/6.jpg)
Technical StuffTechnical Stuff
![Page 7: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/7.jpg)
struct sockaddrstruct sockaddr
struct sockaddr {
unsigned short sa_family;
char sa_data[14];
};
• Address family in this presentation: AF_INET
• Contains a destination address and port number for the socket. The port number is used by thekernel to match an incoming packet to acertain process's socket descriptor.
![Page 8: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/8.jpg)
struct sockaddr_instruct sockaddr_in
struct sockaddr_in { short int sin_family;
unsigned short int sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};
This structure makes it easy to reference elements of the socket address.
Note that sin_zero should be set to all zeroswith the function memset().
![Page 9: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/9.jpg)
struct sockaddr_instruct sockaddr_in
• A pointer to a struct sockaddr_in can be cast to a pointer to a struct sockaddr and vice-versa.
• Also, notice that sin_family corresponds to sa_family in a struct sockaddr and should be set to "AF_INET".
• Finally, the sin_port and sin_addr (unsigned long ) must be in Network Byte Order!
• struct in_addr {
uint32_t s_addr;
};
![Page 10: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/10.jpg)
structsstructs and Data Handling and Data Handling
• A socket descriptor is just a regular int.
• There are two byte orderings:
– Most significant byte first a.k.a. "Network Byte Order".
– Least significant byte first.
• In order to convert "Host Byte Order“ to Network Byte Order, you have to call a function.
![Page 11: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/11.jpg)
Big\Little EndianBig\Little Endian
![Page 12: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/12.jpg)
Convert!Convert!
• There are two types that you can convert: short and. These functions work for the unsigned variations as well. – htons() - "Host to Network Short"
– htonl() - "Host to Network Long"
– ntohs() - "Network to Host Short"
– ntohl() - "Network to Host Long“
• Be portable! Remember: put your bytes inNetwork Byte Order before you put them on the network.
![Page 13: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/13.jpg)
IP Addresses IP Addresses
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
struct sockaddr_in my_addr;
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(3490);
inet_aton("10.12.110.57", &(my_addr.sin_addr));
memset(&(my_addr.sin_zero), '\0', 8);
inet_aton(), unlike practically every other socket-related function, returns non-zero on success,and zero on failure.
![Page 14: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/14.jpg)
Making the ConnectionMaking the Connection
![Page 15: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/15.jpg)
socketsocket system callsystem call
#include <sys/types.h> #include <sys/socket.h> int socket(int domain,
int type, int protocol); • domain - should be set to PF_INET.• type - SOCK_STREAM or SOCK_DGRAM.• protocol - set to 0, Let the kernel choose
the correct protocol based on the type.• socket() simply returns to you a file (i.e.
socket) descriptor that you can use in later system calls, or -1 on error and sets errno tothe error's value.
![Page 16: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/16.jpg)
bindbind system callsystem call
• Once you have a socket, you might have to associate that socket with a port on your local machine (address).
• This is commonly done if you're going to listen() for incoming connections on a specific port.
int bind(int sockfd,
struct sockaddr *my_addr,
int addrlen);
![Page 17: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/17.jpg)
bindbind system call cont.system call cont.
• All ports below 1024 are reserved.
– HTTP 80
– Telnet 23
• You can have any available port number above that, right up to 65535
• In order to use my IP address.
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind() also returns -1 on error and setserrno to the error's value.
![Page 18: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/18.jpg)
bindbind system call cont.system call cont.
• When we get - “Address already in use.”• We can wait, or we can add the following code:
int yes=1;If (setsockopt (listener, SOL_SOCKET, SO_REUSEADDR, &yes,sizeof(int)) == -1)
{perror("setsockopt");exit(1);
}
![Page 19: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/19.jpg)
listenlisten system callsystem call
int listen(int sockfd, int backlog);
• Wait for incoming connections and handle them in some way. The process is two step: first you listen(), then you accept().
• sockfd is the usual socket file descriptor from the socket() system call.
• backlog is the number of connections allowed on the incoming queue.
• As usual, listen() returns -1 and setserrno on error.
![Page 20: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/20.jpg)
Stream StyleStream Style
![Page 21: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/21.jpg)
acceptaccept system callsystem call
Scenario:
• A client will try to connect() to your machine on a port that you are listen()ing on.
• Their connection will be queued up waiting to be accept()ed.
• You call accept() and you tell it to get the pending connection.
• It’ll return to you a brand new socket file descriptor to use for this single connection!
![Page 22: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/22.jpg)
acceptaccept system call cont.system call cont.
int accept(int sockfd, void *addr, int *addrlen);
• sockfd is the listen()ing socket descriptor. • addr will usually be a pointer to a local struct sockaddr_in. This is where the information about the incoming connection will go.
• addrlen is a local integer variable that should be set to sizeof(struct sockaddr_in) before its address is passed to accept().
• As usual, accept() returns -1 and setserrno on error.
![Page 23: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/23.jpg)
connectconnect system callsystem callint connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
• sockfd is socket file descriptor.
• serv_addr is a struct sockaddr containing the destination port and IP address.
• addrlen can be set to sizeof(struct sockaddr).
• Be sure to check the return value fromconnect()-it'll return -1 on error and set the variable errno.
![Page 24: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/24.jpg)
SummarySummary
• if you're going to be listening for incoming connections, the sequence of system calls you'll make is:
– socket();
– bind();
– listen();
– accept();
![Page 25: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/25.jpg)
send()send() system callsystem call
int send(int sockfd, const void *msg, int len, int flags);
sockfd is the socket descriptor you want to send data to.
msg is a pointer to the data you want to send.
len is the length of that data in bytes.
flags set to 0.
send() returns the number of bytes actually sent out. -1 is returned on error, and errno is set to theerror number.
![Page 26: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/26.jpg)
recv()recv() system callsystem call
int recv(int sockfd, void *buf, int len, unsigned int flags);
• sockfd is the socket descriptor to read from• buf is the buffer to read the information
into.• len is the maximum length of the buffer, • flags can again be set to 0. • recv() returns the number of bytes actually
read into the buffer, or -1 on error with errno set, accordingly.
• recv() can return 0. This means the remoteside has closed the connection.
![Page 27: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/27.jpg)
Datagram StyleDatagram Style
![Page 28: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/28.jpg)
sendto()sendto() system callsystem call
int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
• This call is basically the same as the call to send() with the addition of two other pieces of information. – to is a pointer to a struct sockaddr.– tolen can simply be set to sizeof(struct
sockaddr).
• Just like with send(), sendto() returnsthe number of bytes actually sent, or -1 onerror.
![Page 29: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/29.jpg)
recvfrom()recvfrom() system callsystem call
int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen);
• This is just like recv() with the addition of a couple fields.
– from is a pointer to a local struct sockaddr that will be filled with the IP address and port of the originating machine.
– fromlen is a pointer to a local int that should be initialized to sizeof(struct sockaddr). When the function returns, fromlen will contain the length ofthe address actually stored in from.
• recvfrom() returns the number of bytes received,or -1 on error with errno set accordingly.
![Page 30: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/30.jpg)
closeclose system callsystem call
close(sockfd);
This will prevent any more reads and writes to the socket. Anyone attempting to read or write the socket on the remote end will receive an error.
![Page 31: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/31.jpg)
Summary Stream SocketSummary Stream Socket
• Server Side
1. socket();
2. bind();
3. listen();
4. accept();
5. send()/recv()
• Client Side
1. socket();
2. connect();
3. send()/recv()
![Page 32: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/32.jpg)
Summary Datagram SocketSummary Datagram Socket
• Listener side:
1. socket();
2. bind();
3. recvfrom();
• Talker side:
1. socket();
2. connect();//op
3. sendto();
• By using connect(), talker can send \ receive to \ from a specific address. For this purpose, you don't have to use sendto() and recvfrom()you can simply use send() and recv().
![Page 33: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/33.jpg)
Blocking Vs. Non-BlockingBlocking Vs. Non-Blocking
![Page 34: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/34.jpg)
Blocking SynchronousBlocking Synchronous
When you first create the socket descriptor with socket(), the kernel sets it to blocking. If you don't want a socket to be blocking, you have to make a call to fcntl():
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
sockfd = socket(AF_INET, SOCK_STREAM, 0);
fcntl(sockfd, F_SETFL, O_NONBLOCK);
If you try to read from a non-blocking socket and there’sno data there, it’s not allowed to block - it will return -1and errno will be set to EWOULDBLOCK
![Page 35: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/35.jpg)
Blocking Vs. Non BlockingBlocking Vs. Non Blocking
If you put your program in a busy-wait looking for data on the socket, you’ll suck up CPU time. A more elegant solution for checking to see if there’s data waiting to be read comes in synchronous mechanism of select().
![Page 36: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/36.jpg)
select()select()Synchronous I/O Multiplexing Synchronous I/O Multiplexing
select() gives you the power to monitor several sockets at the same time. It will tell you which ones are ready for reading, which are ready for writing, and which sockets have raised exceptions.
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select(int numfds, fd_set *readfds,
fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout);
![Page 37: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/37.jpg)
select()select()
• The parameter numfds should be set to the values of the highest file descriptor plus one.
• In order to manipulate fd_set use the following macros: – FD_ZERO(fd_set *set)
//clears the set
– FD_SET(int fd, fd_set *set)
//adds fd to the set
– FD_CLR(int fd, fd_set *set)
//removes fd from the set
– FD_ISSET(int fd, fd_set *set)
//tests to see if fd is in the set.
![Page 38: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/38.jpg)
select()select()
• If the time specified in struct timeval is exceeded and select() still hasn't found any ready file descriptors, it'll return so you can continue processing.
struct timeval {
int tv_sec; //seconds
int tv_usec; //microseconds
};
• If you set the fields in your struct timeval to 0, select() will timeout immediately, effectivelypolling all the file descriptors in your sets.
• If you set the parameter timeout to NULL, it willnever timeout, and will wait until the first file descriptor is ready.
![Page 39: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/39.jpg)
select()select()
• if you don't care about waiting for a certain set, you can just set it to NULL in the call to select().
• if you have a socket that you are listen()'ing to, you can check for a new connection by putting that socket’s file descriptor in the readfds set.
• On success, select() returns the number ready descriptors contained in the descriptor sets, which may be zero if the timeout expires before anything interesting happens. On error, -1 is returned, and errno is set appropriately;
![Page 40: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/40.jpg)
ExampleExample
int main() { struct timeval tv; fd_set readfds; tv.tv_sec = 2; tv.tv_usec = 500000; FD_ZERO(&readfds); FD_SET(STDIN, &readfds); select(STDIN+1, &readfds,
NULL, NULL, &tv); if (FD_ISSET(STDIN, &readfds))
printf("A key was pressed!\n"); else
printf("Timed out.\n"); return 0;
}
![Page 41: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/41.jpg)
Address Related System CallsAddress Related System Calls
![Page 42: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/42.jpg)
getpeernamegetpeername
The function getpeername() will tell you who is at the other end of a connected stream socket. The synopsis:•int getpeername(int sockfd, struct sockaddr *addr, int *addrlen); •sockfd is the descriptor of the connected stream socket.•addr is a pointer to a struct sockaddr that will hold the information about the other side of the connection, •addrlen is a pointer to an int, that should beinitialized to sizeof(struct sockaddr).
•The function returns -1 on error and setserrno accordingly.
![Page 43: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/43.jpg)
Domain Name Service -Domain Name Service -gethostnamegethostname
• DNS is an acronym for Domain Name Service. This service maps human-readable address (a.k.a. host names) to IP addresses. This allows computers to be accessed remotely by name instead of number.
• The function gethostname() returns the name of the computer that your program is running on. The name can then be used by gethostbyname() to determine the IP address of your local machine.
#include <unistd.h>
int gethostname(char *hostname,
size_t size);
![Page 44: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/44.jpg)
Domain Name Service - Domain Name Service - gethostbynamegethostbyname
#include <netdb.h>
struct hostent *
gethostbyname(const char *name);
returns a pointer to the filled struct hostent, or NULL on error.
![Page 45: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/45.jpg)
struct hostentstruct hostent
struct hostent {
char *h_name;//Official name of the host.
char **h_aliases;//Alternate names.
int h_addrtype;//usually AF_INET.
int h_length;//length of the address.
char **h_addr_list;
//network addresses for the host in N.B.O.
};
#define h_addr h_addr_list[0]
![Page 46: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/46.jpg)
ExampleExample
int main(int argc, char *argv[]) { struct hostent *h; if (argc != 2) {fprintf(stderr, "usage: getip address\n");
exit(1); } if ((h=gethostbyname(argv[1])) == NULL) {herror("gethostbyname");
exit(1); } printf("Host name : %s\n", h->h_name); printf("IP Address : %s\n",
inet_ntoa(*((struct in_addr *)h->h_addr))); return 0;
}
![Page 47: Network Programming](https://reader036.vdocuments.us/reader036/viewer/2022081508/56814937550346895db67b67/html5/thumbnails/47.jpg)
IPv6 - The next-generation IPv6 - The next-generation
• IPv4 is finished (all addresses given out)
• Bigger address space (128 bit)
• More security \ New features
• Supported by all the new operating system butstill not so widespread….