network programming
linux
server
fork
SIGPIPE
Author: WhoAmI
email: kccddb@gmail.com
Date: 20220726
Copyright: CC BY-NC-SA
事實上真正實用的網路程式也不能照此例方式如此寫, 必需有搭配! 這是基本用法之一, 需要了解這基礎!
網路程式設計實用上最難的就是 "能動不代表能用" 但是可學的問題很多, 其中fork, select (epoll, epoll_wait 是加強版)是很重要的 system call, 一定要會. 這不一定只用於網路程式, 用於很多地方, 尤其未來 embedded system I/O 的部分! 另一重點是 thread!
udp 的部分比較容易, 請參考別的文件例如
Beej's Guide to Network Programming.
UDP Client/Server (select)
這裡額外提醒 MTU(Maximum Transmission Unit) 的問題, 例如 VPN, Jambo Frame, PPPoE,… 的狀況
程式中 有些 地方 要特別注意 BUG0 BUG1
網路程式設計是 "盡信書不如無書" 的實際例子, 需要思考真正運用上的問題
不按牌理出牌亂搞, 只要有"電"還能達成任務 才算是可言"穩定"
通常 期末 team work: 傳送 4G 檔案, 可以續傳, 處理 網路斷線等問題+口試
道德经:千里之行始於足下
shell (bash): OnlineGDB 可以練習, 還是用自己的 Linux 方便
練習 find, grep, sudo, cp, tar, mv, rmdir, ip commands, bzip2, top, ps, pstree, strace, strip, vim, nano,…
grep: Linux 匹配文字 grep 指令用法教學與範例, by G. T. Wang
了解Linux I/O 輸入與輸出重新導向,基礎概念教學, by G. T. Wang
Simple TCP server
Please handle signals “SIGCHLD” and "SIGPIPE"
事實 真正實用的網路程式也不能照此如此寫 必需有搭配! 這是基本用法之一, 需要了解!
以 TCP client/server 而言, send packet N 次 不代表 recv packet N 次!!!
timeout 也必須處理, select, epoll, setsockopt, SO_RCVTIMEO, SO_SNDTIMEO,…
網路斷線 也需要處理
signal 要處理
byte order (尤其 不同 CPU)
16 bits, 32 bits, 64 bits,…
網路不穩的問題
如果 server 有多組IP, 多組介面 可以 bind 不同的 IP
…
切記“網路程式能動不代表能用” 穩定是基本
您自己認為 可以, 有可能是 自己 測試 不完整
tcpc.c
$>: man 2 socket
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
domain argument:
Name Purpose Man page
AF_UNIX, AF_LOCAL Local communication unix(7)
AF_INET IPv4 Internet protocols ip(7)
AF_INET6 IPv6 Internet protocols ipv6(7) /etc/gai.conf(5) getaddrinfo(3)
…
AF_NETLINK Kernel user interface device netlink(7)
…
AF_PACKET Low level packet interface packet(7)
//這是大概 基本觀念
//實用還有很多細節考量
struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
}
network byte order
struct sockaddr_in {
sa_family_t sin_family; /* address family: AF_INET /
in_port_t sin_port; / port in network byte order /
struct in_addr sin_addr; / internet address */
};
Internet address
struct in_addr {
uint32_t s_addr; /* address in network byte order */
};
NOT THREAD SAFE!
int gethostname(char *name, size_t len);
The gethostbyname() and gethostbyaddr() functions return the hostent structure or a NULL pointer if an error occurs. On error, the h_errno variable holds an error number. When non-NULL, the return value may point at static data.
It’s not so good. If you need this, please use gethostbyname2().
MT-Unsafe: strtok(), gethostbyname(), gethostbyaddr(),…
strace-trace system calls and signals
Check your program! For example, your program is “client”
$> strace ./client
Find the operation and open files.
IPv4 IPv6 priority (If you use “getaddrinfo”.)
See man 5 /etc/gai.conf
setsid - creates a session and sets the process group ID
setsid() creates a new session if the calling process is not a process group leader. The calling process is the leader of the new session, the process group leader of the new process group, and has no controlling terminal. The process group ID and session ID of the calling process are set to the PID of the calling process. The calling process will be the only process in this new process group and in this new session.
// What is no controlling terminal? Your process will have no STDIN;
//e.g., [$> ./your_program &], your process has no controlling terminal.
small note:
The process group ID of any process equals the PID of the calling process. Thus, in particular, setsid() fails if the calling process is already a process group leader. USE pstree to see process relation.
char *cmd_buffer=“your_program_name”;
pid=fork();
if(pid==0){
setsid();
system(cmd_buffer);
exit(0);
}
See also “pstree”. “pstree” can show the processes relations.
Signal (man 7 signal )
SIGHUP 1 Term Hangup detected on controlling terminal or death of controlling process
SIGINT 2 Term Interrupt from keyboard
SIGQUIT 3 Core Quit from keyboard
SIGILL 4 Core Illegal Instruction
SIGABRT 6 Core Abort signal from abort(3)
SIGFPE 8 Core Floating-point exception
SIGKILL 9 Term Kill signal
SIGSEGV 11 Core Invalid memory reference
SIGPIPE 13 Term Broken pipe: write to pipe with no readers; see pipe(7)
SIGALRM 14 Term Timer signal from alarm(2)
SIGTERM 15 Term Termination signal
SIGCHLD 20,17,18 Ign Child stopped or terminated
more…
Term : Default action is to terminate the process.
Core : Default action is to terminate the process and dump core
Ign :Default action is to ignore the signal. (請看 SIGCHLD )
The signals SIGKILL cannot be caught, blocked, or ignored. (#>: kill -9 pid 就是)
SIGTERM can be caught! (一般 #>: kill pid 就是)
SIGSEGV 是程式執行錯誤的 Signal 例如
不合法的記憶體使用引起的 Signal (小心不一定會出現 SIGSEGV Signal, Why?)
這可能讓程式不穩定~有時可, 有時不行
SIGPIPE write to pipe with no readers, 例如 TCP send ~ 水管斷了
SIGCHLD Child stopped or terminated,
Ign 表示 Default action is to ignore the signal.(是 Parent 知道SIGCHLD , 不是該程式) 如下圖
運作流程:
Process (含 Signal Table, …)
Process 註冊 signal handler (hander_function address) 至 Signal Table
//e.g., signal(SIGPIPE , hander_function )
發生 signal 的意外 (除了 SIGKILL與特別嚴重 signal 以外 )
OS call hander_function(signal_number)
順便一提 killall ––kill processes by name
killall program_name
kill process "program_name"
killall ex1
= kill ex1-pid
kill system call
You can use “kill” system call in your program. Then you can kill (send signal) processes by PID;
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
process1 kill(999,SIGTERM);–––––––––––––>process2 (pid= 999)
send signal SIGTERM to pid 999 |
process2 will die.
有關byte order 可參考很好的文件 Beej’s Guide to Network Programming.
Homework: