3 Z; Z9 F4 J' r/ N. l1 sTCP服务器端和客户端的运行流程$ }$ S* x% Q2 }- J n z
: I. w. R' T& P* t, N; d4 U2 W+ O" Y3 G/ [8 i# { _! w9 X6 B( a
如图,这是一个完整的TCP服务器——客户端的运行流程图,其实我个人认为程序啊,不管哪个语言都是一样,核心就在于算法的设计和函数的调用。那么图中的函数都是什么意思呢?6 r9 |, \4 C3 E4 Z/ m
1 Q& _- O( y2 y& _4 u, ` ! |( X6 q0 v2 K1 o1.创建socket( f& Q+ h7 ^: ~+ q) i: X$ i
socket是一个结构体,被创建在内核中 ( y7 v, b% i4 v T R sockfd=socket(AF_INET,SOCK_STREAM,0); //AF_INT:ipv4, SOCK_STREAM:tcp协议; @. i4 o, k0 D: n: w% y
! A/ B) J2 h7 h$ X0 t3 [& | ' ~- [+ m3 j. K. t7 B9 F2.调用bind函数5 ^6 I+ _; X9 K9 l. s( T6 n* c
将socket和地址(包括ip、port)绑定。% N6 x% v1 o, S. T- }
需要定义一个结构体地址,以便于将port的主机字节序转化成网络字节序 u3 d' B, g x
struct sockaddr_in myaddr; //地址结构体7 a! k9 a! A8 S3 z& ]; y
bind函数$ j, A P Y: u. Z' e6 ]0 O
bind(sockfd,(struct sockaddr*)&myaddr,sizeof(serveraddr)) 6 U5 z; @" v% ?2 w4 b: Y5 j6 J1 I9 v# Q! t9 D
) l# d: x% ]( ?1 @1 C: e3.listen监听,将接收到的客户端连接放入队列 0 K* r# t0 l& ]& d5 d- v listen(sockfd,8) //第二个参数是队列长度 . Y, W- E! v. ~! u, Q: G2 b/ M( w
. M! |! ~. ?+ ]. N: K% t
4.调用accept函数,从队列获取请求,返回socket描 述符4 L7 C% m7 ^# b, F# e0 Q! ~
如果无请求,将会阻塞,直到获得连接 3 {+ D' V3 k" K+ K+ D7 J int fd=accept(sockfd, NULL,NULL);//这边采用默认参数 : Z5 c# |1 M: Z; b! g. T : q: o) o0 r; R % q. v0 P6 E% U1 [$ g# g5.调用read/write进行双向通信 $ O7 W6 w! ~5 E0 s& R3 b2 v ! a+ g: o7 |% N0 ^) E4 X/ o" e5 t/ z. ^
6.关闭accept返回的socket ( g2 W# d* l2 L/ }" y close(scokfd); W: G H6 g* p7 p( c) G" K$ U6 [& l% k& s