Socket Programming Berkeley Sockets & WinSock 2
Introductie Wat is een socket ? Een manier om 2 processen met elkaar te laten communiceren Unix & linux : Berkeley sockets Windows : Winsock (1 en 2) 2 Types Stream sockets Datagram sockets
Datagram Sockets Unreliable, geen garanties over : Aankomst van data Volgorde van ontvangst Tijdstip van ontvangst Op basis van UDP Connection-less Data wordt in afzonderlijke delen verstuurd (datagrammen)
Stream Sockets Reliable, garanties over : Aankomst van pakketten Volgorde van ontvangst Op basis van TCP protocol Connection-oriented Data wordt als 1 stream verstuurd (buffering)
Byte Ordering 2 types : Network Byte Ordering MSB staat vooraan in data type Host Byte Ordering Kan zelfde zijn als NBO of omgekeerd Conversie is mogelijk ahv functies zoals htons(),…
Includes Linux : #include Optioneel : #include Win32 : #include “winsock2.h”
Winsock starten WSAStartup WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ return; } WSACleanup
Error Checking Check altijd de return waarde van een socket functie Linux : errno wordt ingevuld (global var) perror(char *); schrijft de error uit WIN32 : WSAGetLastError() geeft error int terug
Address Families Verschillende types communicatiekanalen & onderliggende protocollen AF_INET Internet protocol sockets AF_UNIX Unix File Descriptors AF_IRDA Infrared communication
Adres Structs Algemene geval : struct sockaddr Specifiek geval (AF_INET): struct sockaddr_in sin_port en sin_addr in Network Byte Order ! struct sockaddr { unsigned short sa_family; /* address family, AF_xxx */ char sa_data[14]; /* 14 bytes of protocol address */ }; struct sockaddr_in { short int sin_family; /* Address family */ unsigned short int sin_port; /* Port number */ struct in_addr sin_addr; /* Internet address */ unsigned char sin_zero[8]; /* Same size as struct sockaddr */ } struct in_addr { unsigned long s_addr; /* that's a 32-bit long, or 4 bytes */}
Conversiefuncties Ip adres in long : unsigned long inet_addr(char *); int inet_aton(const char *cp, struct in_addr *inp); Long naar IP adres : Char * inet_ntoa(struct in_addr); Host <> Network byte order htons() -- "Host to Network Short" htonl() -- "Host to Network Long" ntohs() -- "Network to Host Short" ntohl() -- "Network to Host Long"
Voorbeeld (adres) struct sockaddr_in my_addr; my_addr.sin_family = AF_INET; // host byte order my_addr.sin_port = htons(MYPORT); // short, network byte order inet_aton(“ ", &(my_addr.sin_addr)); memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct struct sockaddr_in my_addr; my_addr.sin_family = AF_INET; // host byte order my_addr.sin_port = htons(MYPORT); // short, network byte order my_addr.sin_addr.s_addr=inet_addr(“ “); memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
Socket() SOCKET socket( int af, int type, int protocol ); int socket(int domain, int type, int protocol); domain, af = AF_INET Type : SOCK_STREAM SOCK_DGRAM Protocol = 0 Geeft socket identifier terug
Bind() int bind(int sockfd, struct sockaddr *my_addr, int addrlen); int bind( SOCKET s, const struct sockaddr* name, int namelen ); Verbindt een socket met een adres Voor connection-oriented sockets Vooral van toepassing voor server applicaties Gebruikt bij vaste poort, bv ftp server = 21 Anders impliciete call (systeem bindt aan beschikbare poort op lokaal systeem)
Connect() int connect(int sockfd, struct sockaddr *serv_addr, int addrlen); int connect( SOCKET s, const struct sockaddr* name, int namelen ); Remote adres en poort invullen in sockaddr Gebruikt voor connection-oriented sockets Remote socket moet in listening state zijn Kan ook gebruikt worden voor datagram sockets (adres wordt intern bijgehouden)
Listen() en Accept() int listen(int sockfd, int backlog); Zet de socket in listening mode Backlog = queue length int accept(int sockfd, void *addr, int *addrlen); Sockfd = listening socket Addr = info over connecterend systeem return value = nieuwe socket !
Send() int send(int sockfd, const void *msg, int len, int flags); Stuurt data over een geconnecteerde socket Return value = effectief aantal verstuurde bytes Is niet altijd gelijk aan len ! Indien return value < len : send call herhalen met resterende data
Recv() int recv(int sockfd, void *buf, int len, unsigned int flags); Return value = aantal ontvangen bytes Indien 0 : Andere zijde heeft connectie verbroken Len geeft maximale buffer size aan Blocking functie Gaat pas verder wanneer data ontvangen is
SendTo() en RecvFrom() int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen); int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen); Datagram sockets Adressen moeten steeds meegegeven worden
IO control int ioctlsocket( SOCKET s, long cmd, u_long* argp); // WIN32 int ioctl(int fildes, int request, /* arg */...); // LINUX Cmd = bv. FIONREAD Geeft aantal bytes weer dat kan gelezen worden met een recv() call
Close() en Shutdown() close(sockfd); int shutdown(int sockfd, int how); Shutdown kan connectie slechts in 1 richting sluiten indien gewenst 0 -- Further receives are disallowed 1 -- Further sends are disallowed 2 -- Further sends and receives are disallowed (like close())
DNS Resolving struct hostent *gethostbyname(const char *name); struct hostent { char *h_name; char **h_aliases; int h_addrtype; int h_length; char **h_addr_list; }; #define h_addr h_addr_list[0] returnt 0 indien naam niet gevonden wordt in dns h_addr is eerste adres uit de lijst
Select() int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); Macro’s : FD_ZERO(fd_set *set) -- clears a file descriptor 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 struct timeval { int tv_sec; // seconds int tv_usec; // microseconds };
Extra informatie Linux : MAN pages ml/reference.html Windows =/library/en- us/winsock/winsock/windows_sockets_api_referen ce_2.asp =/library/en- us/winsock/winsock/windows_sockets_api_referen ce_2.asp