áááºá¹ááá¬áá±á·áááºáááºážáá« âLinux API á á¬á¡á¯ááºááᯠáááºážáá²á·á¡á¬áá¯á¶ááᯠáá«áááºááŒáááºá ááŒáá·áºá á¯á¶áá±á¬áááºážááœáŸááº" (á á¬á¡á¯ááºááá¬áá¬ááŒáẠLinux Programming Interface) áááºážááᯠáá¯ááºáá±áá°á áááºááá¯ááºááœáẠááŸá¬áá°ááá¯ááºááŒá®áž áááá¯ááá¯ážááŸááºážáá¯ááºááᯠáááºá¡áá¯á¶ážááŒá¯áá«áá LinuxAPI 30% áá»áŸá±á¬á·á á»á±áž áááŸááá«áááºá
ááá¯ážáá¬ážááẠá á¬á¡á¯ááºá០áá±á¬ááºáá¯ááºáá»ááº
Sockets- áá¬áá¬áááá¯áá¬
á€á¡áááºážááœááºá áááºáá«ááá²áá²ááŸáá·áº á¡ááŒáá¯ááºáá¬áá¬áá»á¬ážááᯠáá®ááá¯ááºážáá¯ááºááŒááºážá á¡ááŒá±áá¶áá»á¬ážááᯠááœá±ážááœá±ážáááºááŒá áºááŒá®áž á¡ááºáá¬áááºáá¬áá¬á¡ááºááºáá®áá±ážááŸááºážáá»á¬ážááᯠáááºáá®ážááẠááá¯ááá¯ááœááºáá°á á±ááá·áº inetd áá¯áá±á«áºáá±á¬ á¡áá°áž daemon ááá¯áááºáž áá±á·áá¬áá«áááºá
áááºáá¬áááºáá¬ááŸáá·áº á¡ááŒáá¯ááºáá¬áá¬áá»á¬áž
á¡áá¯á¶ážáá»á¬ážáá±á¬ socket-based network server architectures ááŸá áºáá¯ááŸááááºá
-
áááºáá¬áááºáá¬- áá¬áá¬ááẠáá±á¬ááºáááºáá»á¬ážá¡á¬áž áá áºááŒáááºáá»áŸáẠáá áºáŠážááᯠáááºáá±á¬ááºááŸá¯áá±ážáááºá áá±á¬ááºáááºáá áºáŠážáá¶á០áá±á¬ááºážááá¯áá»áẠ(ááá¯á·ááá¯áẠáá±á¬ááºážááá¯áá»ááºá¡áá»á¬ážá¡ááŒá¬áž) ááᯠáŠážá áœá¬áá¯ááºáá±á¬ááºááŒá®áž áá±á¬ááºáá áºáá¯ááá¯á· áááºááœá¬ážáááºá
-
á¡ááŒáá¯ááº- áá¬áá¬ááẠáá¯á¶ážá áœá²áá°áá»á¬ážá áœá¬ááᯠáá áºááŒáá¯ááºááẠáááºáá±á¬ááºááŸá¯áá±ážááẠáá®ááá¯ááºážáá¯ááºáá¬ážáááºá
FIFO áááºážá á®ááŒááºážáá»á¬ážááᯠá¡ááŒá±áá¶ááá·áº áááºáá¬áááºáᬠáá¬áá¬áá áºáá¯á á¥ááá¬ááᯠá¡ááá¯ááºáž 44.8 ááœáẠáááºááŒáá¬ážááŒá®ážááŒá áºáááºá
áááºáá¬áááºáá¬áá¬áá¬áá»á¬ážááẠá¡áá»á¬ážá¡á¬ážááŒáá·áº áá±á¬ááºáááºáá±á¬ááºážááá¯ááŸá¯áá»á¬ážááᯠáá»áŸáá»áŸáá áá»ááºááŒááºá áœá¬áá¯ááºáá±á¬ááºááá¯ááºááá·áº á¡ááŒá±á¡áá±áá»áá¯ážááœááºáᬠááá·áºáá»á±á¬áºáááºá á¡áááºááŒá±á¬áá·áºááá¯áá±á¬áº áá±á¬ááºáááºáá áºáŠážá á®ááẠáááºážáááŸá±á·ááœáẠá¡ááŒá¬ážáá±á¬ááºáááºáá»á¬áž áááºážáá±á¬ááºááŒá®ážáááºá¡áá á á±á¬áá·áºááá¯ááºážááááºá á€áá»ááºážáááºááŸá¯á¡ááœáẠá¡áá¯á¶ážáá»á¬ážáá±á¬ááá á¹á ááŸá¬ client ááŸáá·áº server á¡ááŒá¬áž áá áºáá¯áááºážáá±á¬ áá±á¬ááºážááá¯áá»ááºáá»á¬ážááŸáá·áº áá¯á¶á·ááŒááºááŸá¯áá»á¬ážááᯠáááŸááºááŒááºážáááºááŒá áºáááºá
á¡ááŒáá¯ááºáá¬áá¬áá»á¬ážááẠáá±á¬ááºážááá¯ááŸá¯áá áºáá¯á á®ááᯠáá¯ááºáá±á¬ááºááẠá¡áá»áááºáá»á¬ážá áœá¬ááŒá¬áá±á¬ááá á¹á áá»á¬ážááœááºá ááá¯á·ááá¯áẠclient ááŸáá·áº server ááá¯á·ááẠááŸááºáá»á¬ážáá±á¬áááºáá±á·áá»áºáááŸááºááŸá¯áá»á¬ážááœáẠáá«áááºááá·áºááá á¹á áá»á¬ážááœáẠááá·áºáá»á±á¬áºáá«áááºá á€á¡áááºážááœááºá áá»áœááºá¯ááºááá¯á·ááẠá¡ááŒáá¯ááºáá¬áá¬áá»á¬ážááᯠáá®ááá¯ááºážáá¯ááºááŒááºážá ááá¬ážááá¯ážáá» (ááŸáá·áº á¡ááá¯ážááŸááºážáá¯á¶áž) áááºážáááºážááᯠá¡áááá¡á¬ážááŒáá·áº á¡á¬áá¯á¶á áá¯ááºáááºááŒá áºááŒá®ážá áá±á¬ááºáááºá¡áá áºáá áºáá¯á á®á¡ááœáẠáá®ážááŒá¬ážááá±ážáá¯ááºáááºážá ááºáá áºáᯠáááºáá®ážáááºááŒá áºáááºá á€áá¯ááºáááºážá ááºááẠáá¯á¶ážá áœá²áá°á¡á¬áž áááºáá±á¬ááºááŸá¯áá±ážáááºá¡ááœáẠá¡áá¯ááºá¡á¬ážáá¯á¶ážááᯠáá¯ááºáá±á¬ááºááŒá®áž ááŒá®ážáá¯á¶ážáááºá á€áá¯ááºáááºážá ááºáá áºáá¯á á®ááẠá¡ááŸá®á¡ááá¯áááºážá áœá¬áá¯ááºáá±á¬ááºáá±á¬ááŒá±á¬áá·áºá áá¯á¶ážá áœá²áá°áá»á¬ážá áœá¬ááᯠáá áºááŒáá¯ááºááẠáááºáá±á¬ááºááŸá¯áá±ážááá¯ááºááẠá áááºááá¬áᬠáá¯ááºáááºážá áẠ(ááá) á á¡ááááá¬áááºááŸá¬ áááá¯ááºážááá·áºá¡áá áºáá áºáá¯á á®á¡ááœáẠáá®ážááŒá¬ážááá±ážáá áºáᯠáááºáá®ážáááºááŒá áºááẠ(ááááºážá¡á¬ážááŒáá·áºá áá¯ááºáááºážá ááºáá»á¬ážá¡á á¬áž ááœááºáá»ááºááŸá¯á¡ááá¯ááºážáá»á¬ážááᯠáááºáá®ážááá¯ááºáááº)á
á¡á±á¬ááºáá±á¬áºááŒáá«ááá¹ááá»á¬ážááœááºá áááºáá«ááá²áá²ááŸáá·áº á¡ááŒáá¯ááºá¡ááºáá¬áááºááá¯ááááºážáá±á¬á·ááºáá²ááºáá¬áá¬áá»á¬ážá ááá°áá¬áá»á¬ážááᯠááŒáá·áºááŸá¯áá«áááºá á€áá¬áá¬ááŸá áºáá¯ááẠáááá¯ááºážááá·áºáá¶ááŸáá±ážááá¯á·áá±á¬ áááºááá·áºáááºáá±á·áá»áºáá áºá á±á¬ááºááá¯áááᯠáááá¹áá°ááŒááºáá±ážááá·áº áá²á·áááºáá¶áááºáá±á¬ááºááŸá¯ (RFC 862) áááá¯ážááŸááºážáá±á¬áá¬ážááŸááºážááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºáááºá
áááºááá·áº UDP áá¬áᬠáá²á·áááºáá¶
á€ááŸáá·áº áá±á¬ááºá¡ááá¯ááºážááœáẠáá²á·áááºáá¶áááºáá±á¬ááºááŸá¯á¡ááœáẠáá¬áá¬áá»á¬ážááᯠááááºáááºáá±ážáá«áááºá áááºážááᯠááááºáááºážáá¶áá«áẠ7 ááœááºáááŸáááá¯ááºááŒá®áž UDP ááŸáá·áº TCP ááŸá áºáá¯áá¯á¶ážááœáẠá¡áá¯ááºáá¯ááºááẠ(á€ááááºáááºážááᯠáá®ážááá·áºáá¬ážáá±á¬ááŒá±á¬áá·áº áá²á·áááºáá¶áá¬áá¬ááᯠá á®áá¶ááá·áºááœá²áá°á¡ááœáá·áºá¡áá±ážáá»á¬ážááŒáá·áº áá¯ááºáá±á¬ááºááá«áááº)á
áá²á·áááºáᶠUDP áá¬áá¬ááẠáá±áá¬ááááºáá»á¬ážááᯠá ááºáááºáááŒááºáááºááŸá¯ááŒá®áž áááºážááá¯á·ááááá¹áá°áá»á¬ážááᯠáá±ážááá¯á·áá°áᶠááŒááºáááºáá±ážááá¯á·áááºá áá¬áá¬ááẠáá áºááŒáááºáá»áŸáẠáááºáá±á·áá»áºáá áºáá¯áᬠáá¯ááºáá±á¬ááºááẠááá¯á¡ááºáá±á¬ááŒá±á¬áá·áº áááºáá°áá®áá±á¬ áááá¯áá¬áá áºáá¯ááẠáá¯á¶áá±á¬ááºáááºááŒá áºáááºá áá¬áá¬áá»á¬ážá¡ááœáẠáá±á«ááºážá á®ážááá¯ááºááᯠListing 56.1 ááœáẠááŒáá¬ážáááºá
á á¬áááºážááŒá¯á á¯ááŒááºáž á. id_echo_sv.c ááŸáá·áº id_echo_cl.c áááá¯ááááºáá»á¬ážá¡ááœáẠáá±á«ááºážá á®ážááá¯ááº
#include "inet_sockets.h" /* áá»áœááºá¯ááºááá¯á·á socket á áá¯ááºáá±á¬ááºáá»ááºáá»á¬ážááᯠááŒá±áá¬ááẠ*/
#"tlpi_hdr.h" áá«áááºáááº
#define SERVICE "áá²á·áááºáá¶" /* UDP áááºáá±á¬ááºááŸá¯á¡ááẠ*/
#define BUF_SIZE 500 /* ááá¯áá±áá¬ááááºáá»á¬ážá á¡áá»á¬ážáá¯á¶ážá¡ááœááºá¡á
á¬áž
client ááŸáá·áº server ááŸáááºááá¯ááºááẠ*/
_________________________________________________________________________________ sockets/id_echo.h
á á¬áááºážááŒá¯á á¯ááŒááºáž 56.2 ááẠáá¬áá¬á¡áá±á¬ááºá¡áááºáá±á¬áºááŸá¯ááᯠááŒááááºá á¡á±á¬ááºáá±á¬áºááŒáá«á¡áá»ááºáá»á¬ážááẠááŸááºáá¬ážááá¯ááºáá«áááºá
-
áá¬áá¬ááᯠdaemon áá¯ááºááœááºááá·áºááœááºážáááºá áá»áœááºá¯ááºááá¯á·ááẠá¡ááá¯ááºáž 37.2 ááŸááŒá áºáá¬áá±á¬Daemon() áá¯ááºáá±á¬ááºáá»ááºááá¯á¡áá¯á¶ážááŒá¯áááºá
-
áááá¯ááááºááᯠááá¯ááá¯áá»á áºáá áºá á±áááºá¡ááœááºá áá¯ááºá 55.12 ááœáẠáááºáá®ážáá¬ážáá±á¬ á¡ááºáá¬áááºááá¯ááááºážá áááºáá»á¬ážááŸáá·áº áá¯ááºáá±á¬ááºáááºá¡ááœáẠá á¬ááŒáá·áºááá¯ááºááᯠáá»áœááºá¯ááºááá¯á· á¡áá¯á¶ážááŒá¯áá«áááºá
-
á¡áááºá áá¬áá¬ááẠáá±á¬ááºáááºá¡á¬áž áá¯á¶á·ááŒááºááŸá¯ááᯠáááŒááºáá±ážááá¯ááºáá«áá áááºážááẠsyslog() áá±á«áºááá¯ááŸá¯ááᯠá¡áá¯á¶ážááŒá¯á ááŸááºáááºážááá¯á· áááºáá±á·áá»áºáá áºáᯠáá±ážáá±ážáááºá
áááá·áºá¡ááá®áá±ážááŸááºážáá áºáá¯ááœááºá áá»áœááºá¯ááºááá¯á·ááẠsyslog() ááᯠá¡áá¯á¶ážááŒá¯á áááºáá±á·áá»áºáá»á¬ážááᯠááŸááºáááºážáááºááá·áºá¡ááŒáááºáá±á¡ááœáẠááá·áºáááºáá»ááºá¡áá»áá¯á·ááᯠáá»ááŸááºááá¯ááºááœááºááŸááááºá áááºážááẠá áá áºááŸááºáááºážááᯠááœáŸááºážááá¯ážáá±áá±á¬ ááá¯ááºááá¯ááºáá°áááŒá áºááá¯ááºááŒá±ááᯠáááºááŸá¬ážáá±ážáááºááŒá áºáááºá ááá¯á·á¡ááŒááºá áááºážááẠfsync() ááá¯áá¯á¶ááŸááºá¡á¬ážááŒáá·áºá¡áá¯á¶ážááŒá¯áá±á¬ááŒá±á¬áá·áº syslog() ááá¯á·áá±á«áºááá¯ááŸá¯áá áºáá¯á á®áááºá¡ááœááºá á»á±ážááŒá®ážáááºááá¯ááá±á·áá«ááŸáá·áºá
á á¬áááºážááŒá¯á á¯ááŒááºáž á. UDP áá²á·áááºáá¶áááºáá±á¬ááºááŸá¯ááᯠá¡áá±á¬ááºá¡áááºáá±á¬áºááá·áº áááºáá±á¬ááºážáá¬áá¬
_________________________________________________________________sockets/id_echo_sv.c
#áá«áááºáá«áááºá
#"id_echo.h" áá«áááºáááº
#"become_daemon.h" áá«áááºáááº
int
áááºá(int argcá char *argv[])
{
int sfd;
ssize_t numRead;
socklen_t len;
struct sockaddr_storage claddr;
char buf[BUF_SIZE];
char addrStr[IS_ADDR_STR_LEN];
á¡áááºá (Daemon(0) == -1)
errExit("becomeDaemon");
sfd = inetBind(áááºáá±á¬ááºááŸá¯á SOCK_DGRAMá NULL);
á¡áááºá (sfd == -1) {
syslog(LOG_ERRá "áá¬áᬠáá±á«ááºáá±á«áẠ(%s)" ááᯠááááºáá®ážááá¯ááºáá²á·áá«á
strerror(errno));
ááœááºáá±á«ááº(EXIT_FAILURE);
/* áá±áá¬ááááºáá»á¬ážááᯠáááºáá¶ááŒá®áž áááºážááá¯á·ááᯠáá±ážááá¯á·áá°áá»á¬ážáᶠáááá¹áá°áá»á¬áž ááŒááºáááºáá±ážááá¯á·áá«*/
}
ááá¯á· (;;) {
len = sizeof(struct sockaddr_storage);
numRead = recvfrom(sfdá bufá BUF_SIZEá 0á (struct sockaddr *) &claddrá &len);
á¡áááºá (numRead == -1)
errExit("recvfrom");
if (sendto(sfdá bufá numReadá 0á (struct sockaddr *) &claddrá len)
!= numRead)
syslog(LOG_WARNINGá "%s (%s)" ááá¯á· áá¯á¶á·ááŒááºááŸá¯ áá²á·áááºáááºááŒááºáž á¡ááŸá¬ážá
inetAddressStr((struct sockaddr *) &claddrá lená
addrStrá IS_ADDR_STR_LEN)á
strerror(errno));
}
}
_________________________________________________________________sockets/id_echo_sv.c
áá¬áá¬á áá¯ááºáá±á¬ááºáá»ááºááᯠá ááºážáááºáááºá¡ááœáẠListing 56.3 á០áááá¯ááááºááᯠá¡áá¯á¶ážááŒá¯áá«áááºá áá¯ááºá 55.12 ááœáẠáá®ááœááºáá¬ážááá·áº á¡ááºáá¬áááºááá¯ááááºážá áááºáá»á¬ážááŸáá·áº á¡áá¯ááºáá¯ááºáááºá¡ááœááºáááºáž áááºážááẠá á¬ááŒáá·áºááá¯ááºááᯠá¡áá¯á¶ážááŒá¯áááºá ááá command line argument á¡áá±ááŒáá·áº client program ááẠserver ááœááºáááºááŸááá±á¬ network node áá¡áááºááá¯áá°áá«áááºá client ááẠáá»ááºááŸááá±áá±á¬ á¡ááŒá±á¬ááºážááŒáá»ááºáá áºáá¯á á®ááᯠáá®ážááŒá¬ážáá±áá¬ááááºáá»á¬ážá¡ááŒá Ạáá¬áá¬ááá¯á· áá±ážááá¯á·áᬠáá¯á¶á·ááŒááºááŸá¯ááŒáá·áº áá¬áá¬ááŸáááŸáááá·áºáá±áá¬ááááºáá»á¬ážááᯠáááºááŒá®áž áááá·áºáá¯ááºááá·áºáá±áá¬ááœáẠááá¯ááºážáá áºáá¯áá²ááá¯á· áááºáá±á¬ááºáááºá
á á¬áááºážááŒá¯á á¯ááŒááºáž á. UDP áá²á·áááºáá¶áááºáá±á¬ááºááŸá¯á¡ááœáẠáááá¯ááºážááá·áº
#"id_echo.h" áá«áááºáááº
int
áááºá(int argcá char *argv[])
{
int sfd, j;
size_t len;
ssize_t numRead;
char buf[BUF_SIZE];
if (argc < 2 || strcmp(argv[1]á "--help") == 0)
useErr("%s host msgâŠn", argv[0]);
/* ááá command line argument ááᯠá¡ááŒá±áá¶á áá¬áá¬ááááºá
á¬ááᯠááœá²á·á
ááºážáá« */
sfd = inetConnect(argv[1]á áááºáá±á¬ááºááŸá¯á SOCK_DGRAM);
á¡áááºá (sfd == -1)
fatal("áá¬áᬠsocket ááá¯á· áá»áááºáááºááááá«");
/* áá»ááºááŸááá±á¬ á¡ááŒá±á¬ááºážááŒáá»ááºáá»á¬ážááᯠáá®ážááŒá¬ážáá±áá¬ááááºáá¯á¶á
á¶ááŒáá·áº áá¬áá¬ááá¯á· áá±ážááá¯á·áá«*/
for (j = 2; j < argc; j++) {
len = strlen(argv[j]);
á¡áááºá (áá±áž(sfdá argv[j]á len) != len)
fatal("áá
áºá
áááºáá
áºááá¯ááºáž/áá¡á±á¬ááºááŒááºáá±á¬áá±ážáááº");
numRead = read(sfdá bufá BUF_SIZE);
á¡áááºá (numRead == -1)
errExit("áááºáááº");
printf("[%ld bytes] %.*sn", (long) numRead, (int) numRead, buf);
}
ááœááºáá±á«ááº(EXIT_SUCCESS);
}
_________________________________________________________________sockets/id_echo_cl.c
á¡á±á¬ááºááœáẠserver ááŸáá·áº client instance ááŸá áºáá¯ááᯠrun áá±á¬á¡áá«ááœáẠááœá±á·áááá·áº á¥ááá¬áá áºáá¯ááŒá áºáááºá
$su // áá®ážááá·áºááááºáááºážáá
áºáá¯ááá¯á· áá»áááºáááºááẠá¡áá°ážá¡ááœáá·áºá¡áá±ážáá»á¬áž ááá¯á¡ááºáááºá
á
áá¬ážááŸááº:
# ./id_echo_sv // áá¬áá¬ááẠáá±á¬ááºáá¶áá¯ááºááá¯á· áá±á¬ááºááœá¬ážáá«áááºá
# exit // á
á®áá¶ááá·áºááœá²áá°á¡ááœáá·áºá¡áá±ážááᯠá
áœáá·áºáá«á
$ ./id_echo_cl localhost hello world // á€áááá¯ááºážááá·áºááẠáá±áá¬ááááºááŸá
áºáᯠáá±ážááá¯á·áááºá
[5 bytes] áááºá¹ááá¬áá« // client ááẠáá¬áá¬á០áááŸááá±á¬ áá¯á¶á·ááŒááºááŸá¯ááᯠááŒááááºá
[5 bytes] ááá¹áá¬
$ ./id_echo_cl localhost ááŸá¯ááºáááºááŒááºáž // á€áááá¯ááºážááá·áºááẠáá±áá¬ááááºáá
áºáᯠáá±ážááá¯á·áááºá
[7 bytes] ááŸá¯ááºáááºáá«áááºá
áááºááᬠá¡áááºááŒá±áá«á á±ááá¯á· áá¯áá±á¬ááºážáá«áááº)
source: linux.org.ru