Im Beispielprogramm verwendet der Server die folgenden Funktionen der Socket-Schnittstelle:
getbcamhost(): Rechnereintrag abfragen
socket(): Socket erzeugen
bind(): einem Socket einen Namen zuordnen
listen(): einen Socket auf Verbindungsanforderungen „abhören“
accept(): eine Verbindung über einen Socket annehmen
sendmsg(): eine Nachricht von Socket zu Socket senden / Verbindung bestätigen
recv(): Daten von einem Socket lesen
soc_close(): Socket schließen
Beispiel: Verbindungsorientierter Server bei AF_ISO
/* * Beispiel: ISO SERVER * * DESCRIPTION * 1. getbcamhost - socket - bind - listen - accept - sendmsg * 2. recv * 3. soc_close */ #include <stdio.h> #include <sys.types.h> #include <sys.socket.h> #include <iso.h> #include <netinet.in.h> #include <netdb.h> #define INT 5 #define MAXREC 1000000 #define MAXTSEL 32 #define MAXNSEL 9 main(argc, argv) int argc; char *argv[]; { void error_exit(); int sockfd, newfd, clilen, ret; int tsellen, nsellen; char tsel[MAXTSEL]; char nsel[MAXNSEL]; char buffer [MAXREC]; struct sockaddr_iso cli_addr, serv_addr; struct msghdr message; struct cmsghdr cmessage; strcpy (tsel,"SERVER"); tsellen = strlen(tsel); nsel[MAXNSEL-1] = '\0'; /* BCAM Host-Name besorgen */ errno = 0; if(getbcamhost(nsel,sizeof(nsel)) < 0) error_exit("ISO_svr: getbcamhost failed ",errno); else printf ("getbcamhost OK! (%s)\n",nsel); nsellen = strlen(nsel); /* Socket erzeugen */ errno = 0; if((sockfd = socket(AF_ISO, SOCK_STREAM, 0)) < 0) error_exit("ISO_svr: Socket Creation failed ",errno); else printf("socket OK!\n"); /* Dem Socket einen Namen zuordnen */ memset ((char *) &serv_addr, 0, sizeof(serv_addr)); serv_addr.siso_len = sizeof (struct sockaddr_iso); serv_addr.siso_family = AF_ISO; serv_addr.siso_plen = 0; serv_addr.siso_slen = 0; serv_addr.siso_tlen = tsellen; serv_addr.siso_addr.isoa_len = tsellen + nsellen; memcpy (serv_addr.siso_addr.isoa_genaddr,nsel,nsellen); memcpy (serv_addr.siso_addr.isoa_genaddr + nsellen,tsel,tsellen); errno = 0; if(bind(sockfd, (struct sockaddr_iso *) &serv_addr, sizeof(serv_addr)) < 0) error_exit("ISO_svr: Bind failed ",errno); else printf("bind OK!\n"); /* Beginn mit der Annahme von Verbindungsanforderungen */ errno = 0; if (listen(sockfd, INT) < 0) error_exit("ISO_svr: Listen failed ",errno); else printf("listen OK!\n"); errno = 0; clilen = sizeof(cli_addr); newfd = accept(sockfd, (struct sockaddr_iso *) &cli_addr, &clilen); if(newfd < 0) error_exit("ISO_svr: New Socket Creation failed",errno); else printf("accept OK!\n"); /* Positive Bestaetigung (CONNECTION CONFIRM) des Verbindungsaufbauwunsches. Es wird kein echter Datentransfer ausgefuehrt! */ memset ((char *) &message, 0, sizeof(message)); memset ((char *) &cmessage, 0, sizeof(cmessage)); message.msg_control = (char *) &cmessage; message.msg_controllen = sizeof (struct cmsghdr); cmessage.cmsg_level = SOL_TRANSPORT; cmessage.cmsg_type = TPOPT_CFRM_DATA; cmessage.cmsg_len = sizeof (struct cmsghdr); errno = 0; ret = sendmsg (newfd, (struct msghdr *) &message, 0); if (ret == -1) error_exit("ISO_svr: Sendmsg in Error", errno); else printf("sendmsg OK!(%d)\n",ret); /* Daten von einem Socket lesen */ if ((ret = recv (newfd, buffer, MAXREC, 0)) < 0) { if (errno != EPIPE) /* Broken Pipe */ error_exit("ISO_svr: Receive in Error", errno); } else printf("recv OK!(%d)\n",ret); /* Socket schliessen */ errno = 0; if (soc_close (newfd) < 0) error_exit("ISO_svr: soc_close failed ",errno); else printf("soc_close (newfd) OK!\n"); if (soc_close (sockfd) < 0) error_exit("ISO_svr: soc_close failed ",errno); else printf("soc_close (sockfd) OK!\n"); } /* END MAIN */ void error_exit(estring,erno) char *estring; int erno; { fprintf(stderr,"%s errno=%d\n",estring,erno); perror (estring); exit(erno); }
Im Programmbeispiel zu AF_ISO werden folgende Arbeitsschritte durchgeführt:
- Mit der Funktion getbcamhost() ermittelt der Server den BCAM-Host-Namen.
Mit der Funktion socket() erzeugt der Server einen Kommunikationsendpunkt (Server-Socket) sowie den zugehörigen Deskriptor.
Dem neu generierten Socket ordnet der Server mit bind() einen Namen zu.
Mit listen() wird der (Server-)Socket für die Annahme von Verbindungsanforderungen vorbereitet.
Mit accept() nimmt der (Server-)Socket eine Verbindungsanforderung an.
Mit sendmsg() bestätigt der Server die Verbindungsanforderung (CFRM), d.h. die Verbindung ist nun aufgebaut. Mit sendmsg() wird kein Transfer von Benutzerdaten durchgeführt.
Mit recv() empfängt der (Server-)Socket Benutzerdaten vom Partner-Socket (Client-Socket).
Mit der Funktion soc_close() wird der (Server-)Socket wieder geschlossen.