cncml手绘网
标题: 一个很实用的服务端和客户端进行TCP通信的实例 [打印本页]
作者: admin 时间: 2020-5-9 01:46
标题: 一个很实用的服务端和客户端进行TCP通信的实例
本文给出一个很实用的服务端和客户端进行TCP通信的小例子。具体实现上非常简单,只是平时编写类似程序,具体步骤经常忘记,还要总是查,暂且将其记下来,方便以后参考。
' i% ^) i M5 M8 j! l(1)客户端程序,编写一个文件client.c,内容如下:
/ a8 _+ ? d. i# h3 H: Z6 Y- #include <stdlib.h>$ l& p+ D; g n, I: R- F
- #include <stdio.h>
' |0 t, {& Z3 B! i. R$ q7 b - #include <unistd.h>& ^6 _/ w8 o6 W# j* p0 ^- R5 d. u4 ?2 s
- #include <string.h>
0 ?- F W" K7 M) ? - #include <sys/types.h>
" V* t8 P4 w2 a# ^% r h, T - #include <sys/socket.h>; ]. _: I3 Y9 c/ _3 G
- #include <netinet/in.h>2 g) o1 ?* a/ l; O# v1 ]- ?# R
- #include <netdb.h> /* netdb is necessary for struct hostent */
* h0 a( H J1 X$ E6 K4 F
) N1 V- c% r. \$ Q# m2 X- #define PORT 4321 /* server port */6 A: X6 E8 a q$ @% `( N
- ( A% K# x$ b' t x9 r! v
- #define MAXDATASIZE 1006 m" L! k( ?6 j5 a
5 X& q6 B o" U% _. P$ S7 a# ?- int main(int argc, char *argv[])
) o- g, n5 M& m; `. E - {; M' r4 k$ ?( v( d1 Z v
- int sockfd, num; /* files descriptors */
, i" a( z/ z# n. C9 Y& e& A - char buf[MAXDATASIZE]; /* buf will store received text */
9 [/ l) r5 S0 ^8 Z* L - struct hostent *he; /* structure that will get information about remote host */% X% B- E3 _: u# B. e! z( I% A
- struct sockaddr_in server;
9 A0 }' w* O9 T$ ^ -
8 L/ c# d8 L# w7 P9 ^5 `: C: d - if (argc != 2)& W6 W: E4 m! h" L# d. ]- O* {
- {
( s( E' Z+ `! K. @' F1 I. u, B - printf("Usage: %s <IP Address>\n",argv[0]);
$ M0 @+ L9 ]2 Q+ r3 o - exit(1);
: m% ^2 z2 {7 v& @ - }
% ?- `, l5 F! q4 S5 N4 { -
) ~0 L' k& D, `8 B3 ]4 S - if((he=gethostbyname(argv[1]))==NULL)% Q: a! Y! m2 \
- {; h l8 [, O# E: ~; F+ d
- printf("gethostbyname() error\n");! Y8 I* O7 U' [2 @/ }
- exit(1);
5 h4 l& E- h3 m j- g. X1 z - }7 @+ D% p) ?4 \8 j2 i; A
-
; v, {: l6 ?+ ~ - if((sockfd=socket(AF_INET,SOCK_STREAM, 0))==-1)* O# }( q1 p' e+ F2 {/ C" z/ V
- {) i+ F% b/ k4 u) j. J" ?& \2 e
- printf("socket() error\n");
7 E- O/ A2 J7 i. _0 j/ L0 } - exit(1);
/ P4 u c @/ b _- k; d1 r, E - }
5 E7 p5 ^5 l. g* x7 _& }5 ` - bzero(&server,sizeof(server));
8 i6 @. ]$ z! K, ] - server.sin_family = AF_INET;- T+ t! `" G& u4 N9 N+ f& ~
- server.sin_port = htons(PORT);" x6 Q; |% y* ?2 O* U J! f
- server.sin_addr = *((struct in_addr *)he->h_addr);: B$ c7 T+ m' O8 s
- if(connect(sockfd, (struct sockaddr *)&server, sizeof(server))==-1)
3 x& [ q5 R+ j9 F - {8 J5 e$ s% d8 ?" x9 I, G) ?% \
- printf("connect() error\n");
- q/ P a3 {! H, i; [' t& Z - exit(1);
0 v3 x R& K9 y' S8 ^# G3 {5 F( _ - }( t8 C: o; x3 g* ~& M( P
-
. q x6 h% l* m, e3 P, x8 g - char str[] = "horst\n"7 g; ]! W9 l8 F' [! y
- 2 E2 Y- B7 |8 N2 o& g2 q! n# i; j
- if((num=send(sockfd,str,sizeof(str),0))==-1){5 t/ ~$ u" b/ ]" X" g
- printf("send() error\n");0 p3 O9 M C/ V- g/ M6 ]1 N n
- exit(1);
* s$ ]. Z/ r* z3 u - }' W5 ? |* A" W
- if((num=recv(sockfd,buf,MAXDATASIZE,0))==-1)$ c- n; S' Y+ d ~
- {
6 O* G& Q( ]3 I! p }5 K- T - printf("recv() error\n");5 V( p. A" ^0 I! S, @
- exit(1);
, z2 X$ ]& m( b8 m - }4 z7 \) f+ @, n, a9 u( w$ v; }
- buf[num-1]='\0';
# w: w/ d4 ^% U9 g# E: I7 s - printf("server message: %s\n",buf);$ Q% k @) x2 v. i
- close(sockfd);5 h. r S, F% `' U2 \; r: c3 r
- return 0;. D6 z! \+ N9 K
- }
复制代码 (2)服务器端,编写server.c,内容如下
, e% T. `$ J# B$ A- #include <sys/time.h>2 L1 m- [" \- [( A4 D
- #include <stdlib.h>
* z: d: |9 Y3 M. w - #include <stdio.h>6 |2 [: R( T3 N: `; ~
- #include <string.h>0 z* ?5 `3 h0 C6 i: d
- #include <unistd.h>( o2 u- t3 c K3 a+ ?' N; z6 @
- #include <sys/types.h>* e2 \4 ] e/ k- ~# ~
- #include <sys/socket.h>! F0 |! ]9 ]5 j% ]! B
- #include <netinet/in.h>
q8 h( A' @; j, U6 o2 L' U8 Z3 u( k2 O! Q - #include <arpa/inet.h>) k' V; p. q) {$ b7 y
- 9 K/ Y* u: x' ~ Z6 Q8 A/ y
- #define PORT 4321
: S# G5 l! B8 w+ l) Y" e
3 R) {5 o. G: Z* y- #define BACKLOG 1
5 M( ^; j- ?1 ^7 D. T. u - #define MAXRECVLEN 1024
1 L w1 H9 a, }: n/ q
* A6 L9 c4 P9 f( s9 X# M8 w- int main(int argc, char *argv[])
# Z' F1 U) ^) n/ J - {
& y* ~0 A' a# s+ o3 \9 R0 d - char buf[MAXRECVLEN];- h; C$ r p" s: k- h% o( B
- int listenfd, connectfd; /* socket descriptors */
% |# F, Y* `' [1 j - struct sockaddr_in server; /* server's address information */: a$ [6 q7 i9 v9 _: n- q
- struct sockaddr_in client; /* client's address information */2 @6 a, U* \" w& H: s4 D
- socklen_t addrlen;( T# Q3 q5 E1 d& K6 |% v1 y( Z
- /* Create TCP socket */
" R S3 a/ N8 B* R( l- e - if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)% u8 p: E1 H4 Z+ t' q- ]& `( I
- {9 n0 S4 J M, N' _1 X+ g
- /* handle exception */4 p2 R/ C( j) z; e, p6 y6 E
- perror("socket() error. Failed to initiate a socket");- }/ G) c5 _4 U- [
- exit(1);
" Z, z% U4 H1 v5 u; X - }
" H1 S3 q! ?& J! D4 K -
p; y( K& M! t$ f0 T. [ - /* set socket option */0 E: i4 ?% \; e! @5 o5 w. V/ a1 ]
- int opt = SO_REUSEADDR;
u- T: I1 r9 Q, `, l0 I, F8 m - setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
2 `) d4 v) [4 r0 n$ N) y m - 2 j, t+ y5 B* k6 F% H
- bzero(&server, sizeof(server));
9 K/ @& E/ L" m) Q( l
+ T, U9 }& ]- b- server.sin_family = AF_INET;
8 i- U1 W: {6 o! r6 y+ h - server.sin_port = htons(PORT);
- y% A1 m- h; N2 C. f - server.sin_addr.s_addr = htonl(INADDR_ANY);
3 d% |8 `: E, ]% n; [+ \4 ^ - if(bind(listenfd, (struct sockaddr *)&server, sizeof(server)) == -1)
1 Z& ^! u/ D( v& z4 T; L - {
# F4 q' y! N2 B - /* handle exception */' E) v" j, U: }& f$ f: y
- perror("Bind() error.");
3 l7 J6 ~, B9 ^0 F: d* M - exit(1);0 E& z( ~2 R" ]* t6 l9 V# ?; F
- }
+ X, {) `; q5 _5 s0 k - , ~/ V/ i# H% k0 f
- if(listen(listenfd, BACKLOG) == -1)
$ [( A6 I4 d! J - {" J" n8 \3 q1 ~# `- ?4 B
- perror("listen() error. \n");- A$ L! }& ^" { V( P$ h+ }
- exit(1);
9 V" B0 _/ j9 `: B - }; C. h1 E: b- Z4 y8 O4 c
- / p h7 W. o- }) j. q4 A% W" x
- addrlen = sizeof(client);5 `9 K5 q% b# S5 E% r
- while(1){% A+ P% i& x% O' [
- if((connectfd=accept(listenfd,(struct sockaddr *)&client, &addrlen))==-1)9 V" N' E W6 z7 W7 B+ B' h
- {
; b7 X3 u5 M5 ]# n" N9 j- H3 | - perror("accept() error. \n");
' U* x; `9 S I% S - exit(1);
- N- D; P) u2 z' M& B! M* a+ v2 W; X - }9 M4 }" M6 `: F9 k3 \7 e) I0 n( Z
" [. R$ J7 B2 o7 U6 o- struct timeval tv;
" j; n V) e3 M: A/ O3 w. F9 D - gettimeofday(&tv, NULL);
4 I' r0 c6 Y4 n* e5 U - printf("You got a connection from client's ip %s, port %d at time %ld.%ld\n",inet_ntoa(client.sin_addr),htons(client.sin_port), tv.tv_sec,tv.tv_usec);9 l* B( w: ^) B2 s6 b
- 6 {& p' r9 R% D
- int iret=-1;
+ V1 B; P0 \, n( p* a4 w: r - while(1)
6 F6 }1 h; r! N% o* n - {7 ?0 Q2 V- [, Y
- iret = recv(connectfd, buf, MAXRECVLEN, 0);' \( ^4 \7 X2 Q
- if(iret>0)' C( u# P7 q* Y( C8 S+ ~& y% ^- |2 u
- {
9 {3 U* X5 @5 G - printf("%s\n", buf);+ B& I* f+ v- b4 y, [2 ~9 Y [. a: W3 e
- }else% F: [" L% Y# ?8 J
- {3 n1 i5 U4 D* J
- close(connectfd);$ C% l* C$ P$ ?% H" Y, G" g, F
- break;: G1 w! E- v- f, i7 V- G Z0 C
- }
% J3 U3 b/ \9 ~( C - /* print client's ip and port */
0 o3 s' H7 O7 r - send(connectfd, buf, iret, 0); /* send to the client welcome message */
7 _, |& o) b& F$ c - }/ |9 P; F. Q4 q% a) V
- }
7 P0 S' Q( M' a1 B% s - close(listenfd); /* close listenfd */
7 ^1 C- ?" L! i0 o! d. w - return 0;3 M8 V' } Y+ _. `# u
- }
复制代码 + m5 O/ {4 I5 q4 @* o. ]
$ Z6 O, ?( W$ q6 Y3 l
(3)编译运行
以上两个程序放在同一个目录下,比如 /home/horstxu/Cprog/tcpCSmodel
命令行进入该目录 $ cd /home/horstxu/Cprog/tcpCSmodel
命令行执行 $ gcc -o client client.c ,可以编译出客户端程序。
命令行执行 $ gcc -o server server.c,可以编译出服务端程序。
命令行执行 $ ./server,启动server程序。
这时你可能需要重新打开一个命令行窗口,到刚才的目录下,执行 $ ./client 127.0.0.1,启动客户端程序,就可以看到结果了。
客户端:
- $ ./client 127.0.0.14 R3 _. F6 l6 ~$ S, p0 u5 u% }
- 1 Y8 r1 M8 H X$ }$ n4 X
- server message:horst
复制代码 5 K( H) M' U/ R* j; F
服务器端:
- $./server
8 j7 v' J# {" p- s4 [7 J - you got a connection from client`s ip 127.0.0.1, port 60865 at time 1418281267.643428
复制代码本程序客户端会自动退出,服务器不会,因此如果想停掉服务器程序,直接在命令行界面按键盘Ctrl+C停止。
程序实现的功能很简单,就是服务器监听4321端口,客户端与之建立TCP连接后,再发送字符串“horst\n”到服务端,服务端打印出来,然后再把字符串传回给客户端,客户端再打印出来。然后客户端关闭连接退出,而服务端继续监听4321端口等待下一次连接。
( T! U, g, `6 g6 R2 v) v
# ?9 _" r& m: w' F5 W( W$ W/ z4 i5 R4 E, l$ R: c0 X, ]$ m$ Y
K+ t# s7 d4 G6 w; i, k
作者: admin 时间: 2020-5-9 01:48
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段.! i9 B( s) H8 ^7 ^% C5 ~
- /*client.c*/! x5 F. W9 P1 Q t. H8 n
- #include<netinet/in.h> // for sockaddr_in
9 }% o. o1 ^7 c& Q - #include<sys/types.h> // for socket 8 g( Y; C* u7 S& f' q
- #include<sys/socket.h> // for socket 1 U: D" S" c5 j2 n1 }9 J7 @) c: l
- #include<stdio.h> // for printf
! e- y3 h/ l4 E1 F! Y - #include<stdlib.h> // for exit
) m+ O( y. o M% M& d1 X2 N$ n - #include<string.h> // for bzero
i& r: b" b( k
: P: I* J( k& @' C+ v% Y- #define HELLO_WORLD_SERVER_PORT 6666 ) a+ k' F& p# b t& y, `# N
- #define BUFFER_SIZE 1024 ' |( y+ d% P( S i, S
- #define FILE_NAME_MAX_SIZE 512
4 c' g, X, @# Y6 F' I7 }" c' ~ - / E1 S# p: G& b# s
- int main(int argc, char **argv) : q7 y4 u3 ^% @( w! L0 A
- {
& A5 X, K! v4 b, x. f& g - if (argc != 2) - ~* Z% \4 C9 J, l
- { ) Z6 H8 u' `/ Y/ O3 j' I2 E9 A) j
- printf("Usage: ./%s ServerIPAddress\n", argv[0]); + S' J" X: i9 R; n' D F
- exit(1);
g8 S6 p) w5 [9 r% W' F( R0 o# j# f - }
# n! c. K* S+ z/ h6 ~9 \$ A - 6 h3 o" a, p$ z5 M1 L
- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口 & X- p; b% r: K4 Q
- struct sockaddr_in client_addr; / P+ O* E- u# @/ L1 S
- bzero(&client_addr, sizeof(client_addr)); , ^( M, |/ J( F& q3 u, G: l6 q
- client_addr.sin_family = AF_INET; // internet协议族
8 ~' H& _0 B% W( u - client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址
: y: y) Y& D! M% d5 {# W1 [% ` - client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口 4 _/ @0 M+ G5 y" ]# G X
- 0 H I6 a% \& Q/ j5 A
- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket & H1 _( M" |4 r( A
- int client_socket = socket(AF_INET, SOCK_STREAM, 0);
. F5 J) W4 P$ a# s; g - if (client_socket < 0)
) }! H% O& r2 ?! K8 M - {
! S( ]* s. G1 k$ [* F0 l - printf("Create Socket Failed!\n");
$ t& W1 Y5 O. h4 D - exit(1);
; |% [1 c; |$ _8 L - } + U1 F- c9 V/ I+ c" ~+ j& O7 Z
- . w2 [- }" X9 V! a" i& `
- // 把客户端的socket和客户端的socket地址结构绑定
1 K5 _+ S, M8 x( m - if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr)))
6 e& S# D+ w. A) ` - { - @2 f/ C! M1 I l. N
- printf("Client Bind Port Failed!\n");
; y; n* {4 w+ l- d - exit(1); 3 a: x; ~& a# a7 p. ^
- } 7 _* ]8 `, v! R) k! F$ C7 P
3 O/ |! j, F# [ E( D( O/ ?- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口 * p T% c) L6 T3 y: g
- struct sockaddr_in server_addr;
3 o) h. o$ k8 E( I4 n+ H% N- X - bzero(&server_addr, sizeof(server_addr)); - ]1 t% d5 P. a( x {$ C0 c
- server_addr.sin_family = AF_INET;
( k, w* e! o. S, V - 3 Y; O, r t! G% ?6 r/ N
- // 服务器的IP地址来自程序的参数 / c+ S; X. A, r; l
- if (inet_aton(argv[1], &server_addr.sin_addr) == 0)
; m4 g; n1 U3 ^+ o3 x - {
* @3 N# \9 V+ }2 c - printf("Server IP Address Error!\n"); ( j* Y% \& ]! F7 T$ L9 H1 z4 g; g8 f
- exit(1);
( ~7 x: Q5 X) g% _9 l6 l - }
D$ n& {; c7 v& ` - - D) o! r v* l$ K! m- i5 M
- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
! e$ Z4 e0 E% v1 S& f - socklen_t server_addr_length = sizeof(server_addr);
& \* d; C/ B0 n* y [
' O' h; {: A, B2 v7 D- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接 ' a2 d8 y4 X& g7 }, m: y
- if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0) ) L' `0 T A& ?: W2 ]
- {
8 k# z( x4 }/ s5 x! @. U - printf("Can Not Connect To %s!\n", argv[1]);
4 [& U/ o3 L5 f& R( J" q - exit(1);
1 Y+ s, D& i7 |- Q, q - } 2 E8 p- |" y/ b* i/ o) _! F3 f
d: V! Q6 ?/ k5 A$ J- char file_name[FILE_NAME_MAX_SIZE + 1];
/ t8 ~ X9 G/ Y4 T7 a! Q1 Y9 _7 u. {6 U - bzero(file_name, sizeof(file_name));
$ b6 m: M5 K6 ]. G/ R( N - printf("Please Input File Name On Server.\t");
& V5 L9 j; P7 g) |% D$ a; V - scanf("%s", file_name); 9 _/ U3 A- h* @3 f5 r7 @4 _8 s
- 4 a7 Y% J6 Y& E, ?# p! v
- char buffer[BUFFER_SIZE]; ; k* F1 a( T. Q
- bzero(buffer, sizeof(buffer)); - I4 B' n& ^/ N7 @1 J( Y0 i
- strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name));
. ]8 H+ `1 `5 [% b - // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字 : N4 O8 `5 u6 D6 Y3 W% O' Q
- send(client_socket, buffer, BUFFER_SIZE, 0);
/ s$ @: z4 S+ k; u0 z% n: J
3 X" X* F& x) L- T* P- FILE *fp = fopen(file_name, "w");
0 f% d! ^ e$ u/ p0 c" B" h - if (fp == NULL)
]: h, u& s1 Y+ q. G - {
- M k- A6 r- w0 Z - printf("File:\t%s Can Not Open To Write!\n", file_name);
9 c/ s9 b2 y, M9 \' T - exit(1);
3 c3 P5 B& L9 l! B% T0 E - }
( b A+ Q' s) ?7 S
4 W# |9 \9 e1 R* u3 R& u0 E3 l- // 从服务器端接收数据到buffer中 7 E6 V9 j3 l' @# G. B9 T" G
- bzero(buffer, sizeof(buffer));
! p9 |9 s' F* S% o: R! d - int length = 0;
2 D* a1 \1 O9 T2 y - while(length = recv(client_socket, buffer, BUFFER_SIZE, 0)) # {+ F. C7 i2 Y
- {
/ B! ~2 v: Y# w7 [ - if (length < 0) " p9 i# W8 k0 o2 X4 [) Q
- { / h1 C6 a) C8 t8 }% I0 a. r
- printf("Recieve Data From Server %s Failed!\n", argv[1]); i& Z, K( m% p- q9 r( T
- break; 5 d- r4 Q; X# a4 u# A
- } : D6 L6 F. _; F
- 9 \- | J. H$ }; N2 Z1 G
- int write_length = fwrite(buffer, sizeof(char), length, fp);
" \; r8 k# D$ j& H; y( f - if (write_length < length) ( C: l' a* i7 e/ ]% W0 k/ s
- {
: u7 s$ v7 T% h* R - printf("File:\t%s Write Failed!\n", file_name);
B8 [3 z8 g" P- H! Z- U1 T/ b$ _( r - break; 6 e, |- a0 i! z! w
- }
: T' U9 b. Y" _! E - bzero(buffer, BUFFER_SIZE); 0 U& P& x# ?; k
- } 0 ]) h/ `0 L5 C" m& ]
; N: y2 C2 A/ j- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]); ! Q; n8 t3 d2 n) i; [. g) D1 o/ o
4 h; j/ a6 n2 I- // 传输完毕,关闭socket
* u9 Q+ F# p1 V7 Z - fclose(fp);
. u d' d4 B. O z' \ - close(client_socket); 5 ^( y- o& K3 D
- return 0; + V4 Y; ] u- E" l
- 9 F9 x9 e0 b% m( L9 s( x( l
- } & w7 r g# h4 g! ~% ~- ~: M' N( t
- 6 q2 v7 |6 e% [
复制代码- /*server.c*/
' [. H9 v. c) C Z* U1 N T$ ^ - #include<netinet/in.h>
2 a2 c1 y m9 s. Z" \3 _ - #include<sys/types.h>
) l0 L' p$ W2 e* f$ Q; D' d - #include<sys/socket.h>" z3 P2 B$ v* A$ t! z
- #include<stdio.h>! j" z' w, f! U% D1 z ~6 f
- #include<stdlib.h>' ]. A* @; ]$ {3 S+ _$ [; ^
- #include<string.h>
; f/ v' x# t9 ^3 w# M; g
, W9 v% T* M" W& G7 g1 C) G- #define HELLO_WORLD_SERVER_PORT 6666 //端口号! B$ V/ K, L$ ?& X. J
- #define LENGTH_OF_LISTEN_QUEUE 20
6 l' g& E, E! _8 R8 O) j - #define BUFFER_SIZE 1024 z6 Q0 N" M8 S, [; r
- #define FILE_NAME_MAX_SIZE 512
) {( e, i$ e8 X* w2 _
7 G% l9 J1 Q2 Y# \2 \- int main(int argc, char **argv)
5 u z8 K: y {( g) E# [) k - {: i, e( T4 G1 z4 ?% Z& [& @
- // set socket's address information
3 _ d5 O# Q& Z7 @ - // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口
% T/ i& c' F# F6 |0 K5 t+ m - struct sockaddr_in server_addr;# z" x# H: N. s9 |' u, v
- bzero(&server_addr, sizeof(server_addr));) D1 x) a4 N, _ M+ O# A! K# ]
- server_addr.sin_family = AF_INET;
) w1 o* O. k4 b9 j8 o' ~) [ - server_addr.sin_addr.s_addr = htons(INADDR_ANY);
0 E9 [6 G+ g2 M - server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
% b5 ~3 g& b3 U; W
" b! P) l* j8 `9 _3 ?6 w- // create a stream socket4 z( B) u9 w: C d( x$ }9 j" u
- // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口
; {( b. t( N- y Q - int server_socket = socket(PF_INET, SOCK_STREAM, 0);4 ^! v9 p$ O: |5 i1 x, r; u6 T) B4 \
- if (server_socket < 0)) _+ R$ j' K" |5 F) @3 q. B# ~
- {
2 N& F" G$ b! C/ @7 G) ^- V - printf("Create Socket Failed!\n");4 W3 I8 z+ S* N( ]
- exit(1);3 }7 y6 {; u- J, q1 K
- }
! i8 P7 K! }3 W
" l" ^$ B( ?2 ~, m5 {! R- // 把socket和socket地址结构绑定0 W9 V6 a% G; ]8 \
- if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))
& s5 G% n+ e+ r% k' X" N - {
) B% a2 u, {1 H8 T/ e4 \/ c - printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);
+ P/ B8 R& s9 h: R8 C9 g7 G# Y7 u - exit(1);, v% ^5 K. ^+ ~' b0 V* b
- }
! G5 }* J# I! w# Z! o - + E# e' O# E* x3 E N5 O# y
- // server_socket用于监听
' |* i- l: r$ }1 t3 _. S - if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))
2 U1 J- h* }; k$ N9 j3 Y n* h+ @/ r - {
% t7 K* n4 }4 l O s9 H9 i - printf("Server Listen Failed!\n");3 A- R) p: ^5 T+ |4 N% B+ s# C
- exit(1);
8 }! S# i1 K0 C9 y" x/ R8 | - }; u- d* ^( i( k j5 Z
3 y b; @% c i( m* k' V5 J6 H1 t- // 服务器端一直运行用以持续为客户端提供服务7 B* l# C3 @# c1 J8 R
- while(1)7 _0 L1 i& }2 ^6 V6 o" N
- {
" V0 f [. w" j8 Z - // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept! H- D/ W2 D) e; P
- // 接受此请求,同时将client端的地址和端口等信息写入client_addr中/ a* _7 e4 s3 F& M* C' D6 B/ I
- struct sockaddr_in client_addr;- w0 y- F& u6 w
- socklen_t length = sizeof(client_addr);! v5 {0 L4 Z0 P0 l% {
. ]3 _2 m3 z% @/ r. I% L: K5 i p8 {+ C- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中
0 k& x6 I# I2 d. I" y+ U - // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以
3 e7 i' |+ q) v3 {( B3 s1 e! h - // 用select()来实现超时检测
# n/ n# l8 ~# Q4 |( \ - // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信
* i" ~8 f2 b" w! e4 A) j - // 这里的new_server_socket代表了这个通信通道
5 }) S9 l! @1 n" u+ s, f7 N$ ~9 S - int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);
; O* k3 o# ~! u8 f/ N) t$ I" ^& ]5 W - if (new_server_socket < 0)6 C5 x" }; g& Q3 I: V
- {
* P7 C9 T4 X( R - printf("Server Accept Failed!\n");
& u9 H+ N5 {: G: g' C' T1 f5 n! E - break;
2 e2 g0 f3 K6 s$ @ n - }7 q) {0 r5 h n1 z% Y
- 8 J1 P$ E* P n0 A, ?
- char buffer[BUFFER_SIZE];
) @' r- i2 s% p7 s: v' Q - bzero(buffer, sizeof(buffer));
6 d2 C& Z" W# C4 Z - length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);% k9 K6 t& a8 ]& {$ T
- if (length < 0)
2 I5 r0 ]! s5 O% H - { I; k& e+ ] \# L; N0 U
- printf("Server Recieve Data Failed!\n");
1 t1 P- R' a9 _# X/ O1 U1 b - break;
4 q3 l( _* K6 P; _2 i+ D) ?% O. ?2 u - }% X* S% f7 `6 a! \
- $ g& C0 T4 r' l* }7 E
- char file_name[FILE_NAME_MAX_SIZE + 1];1 q; ]5 h" @- }2 n) L, B2 `
- bzero(file_name, sizeof(file_name));* {1 W L H! X8 b
- strncpy(file_name, buffer,' w3 D- ]9 c# j7 b2 ~ e) ^$ T2 V& b
- strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));
, F2 X+ O. F) _5 ~3 O8 I! q
3 }' ?! P9 w0 a0 h6 W5 w- FILE *fp = fopen(file_name, "r");" f2 n4 J0 M( W4 f5 a& A
- if (fp == NULL)8 A/ M3 `7 Z2 T
- {# D+ x- D$ l/ T1 ?( k6 z
- printf("File:\t%s Not Found!\n", file_name);
5 c6 r2 G: u+ G, b - }3 u7 h$ t' } j
- else
$ @( `+ _$ k( ?. y: u; C - {
& m) Y5 j# m& g3 L) h0 n" o) X0 } - bzero(buffer, BUFFER_SIZE);
7 U5 N: j2 {4 R( b/ U4 c - int file_block_length = 0;
+ a; y. F" q) j - while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)& `( j0 o7 T% x& p2 S1 k
- {& \; U7 ]7 F0 [) u) Q7 v- y
- printf("file_block_length = %d\n", file_block_length);
6 l$ R+ J* X% } R% R - , p* n5 \+ N. z! p# {
- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端
+ M4 T4 H+ |, G" n2 W- v+ d: v - if (send(new_server_socket, buffer, file_block_length, 0) < 0)* Y7 u. n. j/ Q. Q+ b! v9 M: e
- {
& d- w& ?* Y1 t6 a) [5 V# Q4 D - printf("Send File:\t%s Failed!\n", file_name);% m0 V% D" ^8 n" G
- break;
) a# ^0 j+ B$ A% u - }& u8 `" e) r- q9 M8 s
- ( A0 m2 |4 @) Y/ D2 l& [1 b6 _
- bzero(buffer, sizeof(buffer));* K" ?3 P3 V0 B+ [2 [! r! m; n3 r
- }
2 d6 t2 n3 U: p - fclose(fp);
* e) f m' `: H! o) i8 t5 h; t" O - printf("File:\t%s Transfer Finished!\n", file_name);
! F4 q! `' a5 f+ V - }4 n0 h# a$ E" |+ w% u" ~: O
/ {% X5 W* v! G7 k- g4 u- close(new_server_socket);
0 \7 j6 g4 [6 x$ H( q - }
. A5 a" Z$ {% N0 L \ - 5 f ]' _" Q9 A+ p5 a7 c8 e
- close(server_socket);' ^! _# S- M( h+ z
- ; Z4 j/ q' k- O) }
- return 0;; D+ @1 y, V0 x a! @
- }8 X1 p3 p% G I- v3 \, ^. k: K
, x5 P. W5 I. ^. X0 d0 D$ o, G7 Q
复制代码
1 i: [: E$ y0 i% u- Y; f* h# D
% F$ D+ c# ^) @; x5 ]* k3 ~: j2 N9 Y% d+ u0 _
/ t$ L9 J0 x$ |/ K$ W8 x( @
欢迎光临 cncml手绘网 (http://bbs.cncml.com/) |
Powered by Discuz! X3.2 |