& m) j. ^4 s4 c' z% W- [$ j4 W" z
TCP服务器端和客户端的运行流程& `% W2 [, x/ y: i+ h A2 \) r) y
# l9 _0 D7 B: s. z% H
7 h% _; o2 y7 T. K- B
如图,这是一个完整的TCP服务器——客户端的运行流程图,其实我个人认为程序啊,不管哪个语言都是一样,核心就在于算法的设计和函数的调用。那么图中的函数都是什么意思呢?5 Y7 j' s( E' N$ o
9 M; f& M% m0 q: W! v
; U0 @, z( }: p5 D# i8 k
1.创建socket5 g8 K+ j. R5 H: D
socket是一个结构体,被创建在内核中 / a2 ^. V( ` b* _ h; J$ h sockfd=socket(AF_INET,SOCK_STREAM,0); //AF_INT:ipv4, SOCK_STREAM:tcp协议) A8 F. d3 r7 X) b- ~) ]6 Q
* S4 g" v$ k9 O+ u" T. _9 h2 K9 f1 A6 v& R/ l- @
2.调用bind函数 4 f$ `" a M- a& K: } 将socket和地址(包括ip、port)绑定。 e. V- ^3 |% N
需要定义一个结构体地址,以便于将port的主机字节序转化成网络字节序$ u1 o& a2 g: [( P& p
struct sockaddr_in myaddr; //地址结构体 % L) N/ p9 P z+ l" C: f' s bind函数7 |# h+ d2 _! d# o8 G- v! x; `
bind(sockfd,(struct sockaddr*)&myaddr,sizeof(serveraddr))7 C9 i9 }# D) g! ?
2 T6 M. O& @& a0 M a! k' U' Y: h
3.listen监听,将接收到的客户端连接放入队列 T' I+ y8 I, [8 A
listen(sockfd,8) //第二个参数是队列长度; }. b: Q. K6 q9 q+ m2 H
# _5 I0 G; @) `% q4 M. O
. R8 q2 Y& E# [8 }3 }( y* F
4.调用accept函数,从队列获取请求,返回socket描 述符( y* g; C. E8 D( m# X
如果无请求,将会阻塞,直到获得连接 ( P. ]+ S4 N q+ l8 `: R int fd=accept(sockfd, NULL,NULL);//这边采用默认参数 ' ?2 Y# v, M/ z' f# s% J1 v, W: E+ d+ y5 F! T
" o- r& {$ i. l6 o4 Y' m/ h
5.调用read/write进行双向通信 ! H+ p' y$ I" t$ x8 a; P \; M # g8 \; _! u3 {5 |) u: ^ . _; ?( @3 V& J; t) v+ J+ @4 O6.关闭accept返回的socket. Y3 e. m9 x7 H: b( _
close(scokfd);! C9 {0 G: G( P& C$ u# z
1 g2 H; i+ `$ E6 x# D" A, j) t* P" `) {/ T2 _2 ]
7 E, M! t. A0 H
; s9 v, p. v# P O+ J4 K! B# H下面放出完整代码5 _# T% D* V7 `' O1 V* e
' Q5 `' N, N! [" q
/*服务器*/ . {% V _" g# j7 S; X# e
#include <stdio.h> 9 C1 p. |* }1 y9 T. ~
#include <string.h> * F4 b9 P$ W, j$ b' U
#include <stdlib.h>3 n7 b7 y3 J& n5 q8 f' r
#include <strings.h>4 r- Q/ D F% P
#include <sys/types.h> . U! w+ ~# x! s# h
#include <sys/socket.h>+ ?) w& a, F. l( f
#include <arpa/inet.h>$ `& _- G, z* T
#include <netinet/in.h> . w0 p0 E& i. B, y Y
int main()5 v+ q3 `" S- E
{ 7 H: u6 J7 r0 ?; V
int sockfd = socket(AF_INET, SOCK_STREAM, 0);//创建套接字 {' E- ^& Q0 j; P
if (sockfd < 0) 3 E) d: }7 B. H0 L* S, D# [
{ % ]- c5 X/ \' R
perror("socket"); $ u9 x! z: w3 `6 [
return -1; : S# i) S3 f, y9 m F5 I5 d
} //创建失败的错误处理# h2 i& q% d% G- k, p/ Q. }: {
printf("socket..............8 }" M! n/ }2 M. ~! t8 V( B
"); //成功则打印“socket。。。。”/ V/ |# _. s/ D
- |" p6 E' _/ Y
struct sockaddr_in myaddr; //创建“我的地址”结构体! ^% c) c( x& d/ b, L& _7 O+ o