僅用 三個進程 即可與所有客戶機建立並持久保持連接,兼具低進程開銷與隨機訪問能力,適合客戶機多、業務繁忙場景。
L0。L0。L1(讀連接)和 L2(寫連接),將 socket handle 存入共享內存。L1 讀 socket,有數據則讀取並標記來源記錄號。L2 寫 socket,發送響應。struct servent *sp;
struct sockaddr_in peeraddr_in, myaddr_in;
linkf = 0;
sp = getservbyname("tcp_server", "tcp");
ls = socket(AF_INET, SOCK_STREAM, 0);
myaddr_in.sin_addr.s_addr = INADDR_ANY;
myaddr_in.sin_port = sp->s_port;
bind(ls, &myaddr_in, sizeof(struct sockaddr_in));
listen(ls, 5);
qid3 = msgget(MSGKEY3, 0x1ff);
qid4 = msgget(MSGKEY4, 0x1ff);
signal(SIGCLD, SIG_IGN); // 避免僵屍進程
setsockopt(s, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)); // 避免 TIME_WAIT
setpgrp();
switch(fork()) {
case -1: exit(1);
case 0: // Daemon
for(;;) {
s = accept(ls, &peeraddr_in, &addrlen);
setsockopt(s, SOL_SOCKET, SO_LINGER, &linger, lingerlen);
server(); // 處理初始連接登記
close(s);
}
default:
fprintf(stderr, "初始進程退出,守護進程監聽中...\n");
}
msgget)實現進程間共享內存索引。SO_LINGER 置 0 避免 TIME_WAIT 狀態積壓端口。SIGCLD 忽略防止子進程成僵屍。/etc/services 登記公用端口:tcp_server 2000/tcp。