240 likes | 370 Views
Socket Programming. Berkeley Sockets & WinSock 2. http://www.ecst.csuchico.edu/~beej/guide/net/. 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
E N D
Socket Programming Berkeley Sockets & WinSock 2 http://www.ecst.csuchico.edu/~beej/guide/net/
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 <sys/types.h> • #include <sys/socket.h> • Optioneel : • #include <netinet/in.h> • #include <netdb.h> • 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(“172.18.254.254", &(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(“172.18.254.254“); 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); • returnt 0 indien naam niet gevonden wordt in dns • h_addr is eerste adres uit de lijst 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]
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 • http://www.ecst.csuchico.edu/~beej/guide/net/html/reference.html • Windows • http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/windows_sockets_api_reference_2.asp • http://www.sockets.com/