Socket Programming
description
Transcript of Socket Programming
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 WSAStartupWORD 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);
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 http://www.ecst.csuchico.edu/~beej/guide/
net/html/reference.html
Windows http://msdn.microsoft.com/library/default.as
p?url=/library/en-us/winsock/winsock/windows_sockets_api_reference_2.asp
http://www.sockets.com/