管理员
论坛积分
分
威望 点
贡献值 个
金币 枚
|
沙发
楼主 |
发表于 2020-5-9 01:48:09
|
只看该作者
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段.
: A+ v. J2 S4 A8 R5 g, g+ H- /*client.c*/- x" v2 I: Y l" {
- #include<netinet/in.h> // for sockaddr_in
2 N. H( h" n/ k; f/ \ - #include<sys/types.h> // for socket 5 }# q0 s' A3 n% r% l. t9 G# C
- #include<sys/socket.h> // for socket
4 F, t w5 Q+ ^ - #include<stdio.h> // for printf
2 ?8 Q* O9 d& [9 x0 H; s - #include<stdlib.h> // for exit 2 e1 \- q- O2 z8 X7 M$ q' H
- #include<string.h> // for bzero + R% V1 T# K" x& `0 n
7 w f! @9 W( U; v0 n/ E1 J- #define HELLO_WORLD_SERVER_PORT 6666
* d; t% g7 W C& N% g# q. Q - #define BUFFER_SIZE 1024 0 T$ p t! S9 ^+ w' P e
- #define FILE_NAME_MAX_SIZE 512
; q3 t N: H1 g - - P- m7 Z7 \" T: M6 b
- int main(int argc, char **argv)
7 c) S9 X4 j( b ^' G - { $ v' r8 f2 ]& T/ F# f* f5 {
- if (argc != 2)
' @% T' H" ?1 I7 t4 L0 Z* D - { , Q; ~: X3 g" Q! C. }
- printf("Usage: ./%s ServerIPAddress\n", argv[0]); ! m+ f6 U9 y4 I, o7 I. D
- exit(1);
; d; i% \- d& }1 w: K - } ; v8 V# I! z* V
- - J, `# G6 g9 ~! D v
- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口
' E8 o1 h& Z" s& m+ E; T( d - struct sockaddr_in client_addr; * |# e+ |' d2 X, h
- bzero(&client_addr, sizeof(client_addr));
/ L; C% J5 `7 C! C7 I1 B5 | - client_addr.sin_family = AF_INET; // internet协议族 3 z% B# a7 s% ^
- client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址 , \) i ?. G# V; x, S
- client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口
2 F0 Z7 |' J+ Y5 C8 o- D
7 F0 F$ N; f9 Q- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket
; N1 K' f% [3 m' {; D: X4 t7 T - int client_socket = socket(AF_INET, SOCK_STREAM, 0);
7 F! Z* }4 @! _, y# a' } - if (client_socket < 0) " J Z0 X- U, w8 j5 e# I
- {
. x& G% V( v2 w% @* a. r* a$ J. z j - printf("Create Socket Failed!\n"); 7 L3 I' S" m1 @! P9 C* D
- exit(1); ! I! l0 P% O( d, Y" R6 _# U; |' {4 d
- } / `6 y' x$ p/ Z5 M* A- v: ^* O
- \( Q4 I/ g5 _; f7 D- n. d2 E
- // 把客户端的socket和客户端的socket地址结构绑定
, G: V$ P1 u& H: x - if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr)))
/ ~4 _! K9 F: n: N4 n - { - `& n3 D- E! [( g8 O4 @" a
- printf("Client Bind Port Failed!\n");
; K' T" j3 j) [# k% Z- Z+ q$ c - exit(1);
+ n. _. N1 v$ [7 R - } - I1 k/ e! ]: z; ?
- 4 [8 h) ]- f& n& l
- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口 Y$ G) Y3 Z, |& x4 `
- struct sockaddr_in server_addr;
- Q5 R3 l0 q; \: D - bzero(&server_addr, sizeof(server_addr));
7 d* {! t' O* p$ F - server_addr.sin_family = AF_INET; 5 r. c' U) \2 N
- ) L( p3 Z( I' a4 c0 h
- // 服务器的IP地址来自程序的参数 ; T3 J% `1 w1 g8 x
- if (inet_aton(argv[1], &server_addr.sin_addr) == 0)
+ k0 p6 Z: D0 C* r9 Z+ Z, R - { 7 p; y* s6 N, H W. s8 \: t& K
- printf("Server IP Address Error!\n"); . n" |" U1 [: V, e
- exit(1);
" h9 z' V0 u0 Q' p. C) F - }
, B! I" A4 m( ^/ ?( ?
8 M/ l' n- S! S1 A5 V8 v: w8 Z" u- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
4 c7 X% E- H8 Q7 l - socklen_t server_addr_length = sizeof(server_addr); - g% n# i5 u. P
- . G' ]$ b) ^5 J$ _
- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接
9 e: F8 K- A1 P2 l - if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0)
- |3 U0 O, i: X$ O4 h6 `5 K - { $ ?$ i6 j" f0 T( p. f
- printf("Can Not Connect To %s!\n", argv[1]); " [- A' b4 P- W5 v
- exit(1);
8 V$ g; ?0 B, n" ?; a+ { - } 5 X6 [( Z, [0 y
0 W! f( _- F0 I% U- char file_name[FILE_NAME_MAX_SIZE + 1]; / Z" H4 E f; }. }1 c: e' n9 K
- bzero(file_name, sizeof(file_name)); % F K4 Y/ W+ i$ B. u
- printf("Please Input File Name On Server.\t"); & B( x( M) g6 g8 w3 b! R
- scanf("%s", file_name); 6 ?0 K! F3 t- ^6 }, j. A6 c: `( k
- , ]3 e3 M+ t( v, e8 U7 {
- char buffer[BUFFER_SIZE]; ! O* U( V& c3 I
- bzero(buffer, sizeof(buffer)); # a) C, W6 x% k
- strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name));
2 D* L4 _5 O6 l* x+ k - // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字 , R3 ?( a' o: b; }, e/ h4 v9 W" Y
- send(client_socket, buffer, BUFFER_SIZE, 0); & z. ^( w3 \4 {1 y" {' d0 b
+ t4 @+ ?7 q1 C4 z- FILE *fp = fopen(file_name, "w");
7 @0 \. l3 h! [* }8 ~) Z - if (fp == NULL) * O7 |2 R m% i& i# j
- { 8 ~. C$ x3 }6 F
- printf("File:\t%s Can Not Open To Write!\n", file_name);
/ |" ]: Y' ^$ Q1 y - exit(1); 1 P( o: n' i! b
- } ! j+ E8 \! c0 t- o
3 W2 F0 A1 {! }, V8 Q9 P+ v/ F; o- // 从服务器端接收数据到buffer中 + e8 @0 \+ U# s4 \: a; y* r8 T: V
- bzero(buffer, sizeof(buffer));
+ ]( a8 A$ h* }0 n+ ~ - int length = 0;
, s9 K7 P* p7 d+ z# i - while(length = recv(client_socket, buffer, BUFFER_SIZE, 0))
( L: i# D# W! ]) `: j, e7 R9 W - { 0 n# ^0 [+ M0 X* r9 u, G; o) w5 a: H
- if (length < 0)
3 y. s- [8 D; L) q5 V% |" d* N - { 8 L3 ~5 p: F0 ~
- printf("Recieve Data From Server %s Failed!\n", argv[1]); # h) `! G/ c8 L) i. {+ U
- break;
6 \3 f- V4 D/ b4 q6 W6 Z& n( { - } ( g* a6 ^. H4 {& |' Z
/ v$ J) g* o2 p$ \7 `- int write_length = fwrite(buffer, sizeof(char), length, fp);
2 O$ S3 @1 |8 H' i# h2 G - if (write_length < length) 5 M* P; t5 z7 e9 ?- l
- { 6 Y e! \; }$ W6 S' ~ F
- printf("File:\t%s Write Failed!\n", file_name); . @8 ~2 i0 g/ ?' D! }( Z7 g+ [/ ^" W
- break;
7 h* k7 Z8 G& u: ^ - }
3 f [/ ]- I: C* u0 j; K - bzero(buffer, BUFFER_SIZE); 6 w5 K9 |$ k& o; t2 U" W9 ~, k
- } + g* G, C- d* y: O2 A
! y' u" M- `0 i) f, i- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]); g' U/ a5 h6 q0 y# f
- 6 ]1 p5 D5 e& W; z
- // 传输完毕,关闭socket
% m' ]' W" \5 f& M/ ` - fclose(fp); ; R( V/ N$ N$ f$ J+ p) W
- close(client_socket); : _, w0 E7 j s" ^' i9 Q) l$ f# ?9 C& Z
- return 0; 3 ^; b1 B9 C9 |7 f
( ]2 s$ p8 d, j$ x! l- } ! b6 R" V) L" e+ F8 g
8 V: ^4 \% A0 D& Z! c* |
复制代码- /*server.c*/ P6 Y' h$ W% ?! ?1 Y1 v
- #include<netinet/in.h>' r5 B/ c9 w5 M% R
- #include<sys/types.h>$ F# o4 I. f; V8 V
- #include<sys/socket.h>0 U! {: u. p+ @
- #include<stdio.h>$ y8 L$ @3 D( y+ P3 ~# u
- #include<stdlib.h>
0 T3 G& |7 p& `/ r - #include<string.h>
" Q% V7 H1 P& h: \5 }, R - 0 y- r8 S3 A. r/ E8 ^0 {; w
- #define HELLO_WORLD_SERVER_PORT 6666 //端口号. C/ H8 a7 z1 O: Y) Z
- #define LENGTH_OF_LISTEN_QUEUE 20 Y7 f4 R2 g9 B
- #define BUFFER_SIZE 1024; }$ l w3 Z; O6 S& L) c
- #define FILE_NAME_MAX_SIZE 512+ }4 z' r8 R+ x) i/ ^& |5 N, R0 h
- 1 G1 ]# t+ A0 q: R- c4 g
- int main(int argc, char **argv); Q) K1 i* Q# S
- {: O& P( n: p- O! ~1 s1 n7 c- W
- // set socket's address information
/ `2 s+ J8 a* E5 t# x& s - // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口
; r: x) n$ j- M4 o: g - struct sockaddr_in server_addr;3 U" ^% D% h. S; x, k/ H7 S/ g
- bzero(&server_addr, sizeof(server_addr));5 Z* P+ C4 |' @8 B3 O/ t6 K. u, @0 ^
- server_addr.sin_family = AF_INET;9 J7 i9 d; G" N( N9 |- f
- server_addr.sin_addr.s_addr = htons(INADDR_ANY);
) n) I1 N+ o6 I1 J+ I1 M! n- F - server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
3 ^9 F9 g) K; O" ?* a) \ - % a# f+ k- V {% e- \7 B
- // create a stream socket
$ e2 @: `% I& o% K - // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口
; ?3 d0 f: o3 `6 A - int server_socket = socket(PF_INET, SOCK_STREAM, 0);/ F. d& g7 l: o; H
- if (server_socket < 0)
! `% n, `6 @ N/ B" P$ l# Y - {
- G3 d3 m0 q/ t - printf("Create Socket Failed!\n");
4 u1 X [8 A( Z/ t6 b6 X% v9 S - exit(1);
/ a( b7 ^2 t1 ?% q3 q - }
( k" O3 X# ]$ j- g3 C) e" z m
. C, R8 S! c- H+ G7 K% F4 i- // 把socket和socket地址结构绑定8 T% y* K; I2 k9 @& Q
- if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))% A' I* M y9 m% C
- {7 \! b7 n+ M. L$ W# A; t6 S
- printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);& `; g- d7 p0 @9 s6 o* h
- exit(1);5 g% A- j& r) @9 U" ~
- }
4 N N) Z9 C1 Q( J" Y9 U2 T
x+ m( [. K2 P; n- k- // server_socket用于监听, N# b, {$ B. G! ^* [6 l9 B
- if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))
4 M) g' Y' |6 A1 w - {
) c3 s8 `' q( P5 o - printf("Server Listen Failed!\n");2 q+ T( [7 V" ~5 t+ R. u% x/ O
- exit(1);8 p9 }* B; O% \1 ~7 T
- }
5 L: @4 l w6 R V9 T - - r2 V- C# K9 S: w
- // 服务器端一直运行用以持续为客户端提供服务 S/ S g) I& d
- while(1)
# y$ n$ `7 ]# }4 y" m) R l - {
- M9 G' `* X- y+ }6 @& @ - // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept
8 A) ]# V0 z: q% y7 }/ I; m& [ - // 接受此请求,同时将client端的地址和端口等信息写入client_addr中" }4 `2 ?9 b: p9 u9 p
- struct sockaddr_in client_addr;) r7 x& p' |6 a* f0 z
- socklen_t length = sizeof(client_addr);
" a; q+ w/ U9 l" q" K - ' h. w$ p* w* d: Z6 k8 K' `& p( C
- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中
$ p: S+ g- V' ]1 b4 D" Z0 x - // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以
. Z5 @- I x$ G2 l - // 用select()来实现超时检测
& C* _; I2 f' |. i! N - // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信- Z/ \# X, G7 z5 l% ]) F' Q% T
- // 这里的new_server_socket代表了这个通信通道
0 }9 K9 l8 g& V" B# ~ - int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);+ a: q$ i% P+ V1 a, Q
- if (new_server_socket < 0)
3 s4 g6 w+ {& \( H; I - {
" ]! L P5 o+ f& X+ [ - printf("Server Accept Failed!\n");
+ ?! l( _ M4 g" U; h, s& n j - break;) Y; ~- ?% Y% K9 X
- }
) Y: L6 p9 Q9 N: T - - k6 G! W. ]! P0 K1 M
- char buffer[BUFFER_SIZE];
- v( @) A: h% e - bzero(buffer, sizeof(buffer));
3 ?6 d+ @$ i; T$ ]+ v - length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);% J, p# \5 ?) U! D# ]9 \3 y
- if (length < 0)) e( ? t/ d/ T; q( @6 o
- {9 o. S0 H7 f9 v8 p! Y6 J, K
- printf("Server Recieve Data Failed!\n");
( t5 e8 ?, ~% e5 C* c2 ~' t a - break; _: a# b: }" _' ?
- }/ ]0 o Z; `% @% J0 B7 R+ U. R
$ M8 {' D% \* v& L: b) Z7 z1 Z* ?- char file_name[FILE_NAME_MAX_SIZE + 1];
) \9 z Y" o& `' Y - bzero(file_name, sizeof(file_name));: C, L$ T/ O" {+ \
- strncpy(file_name, buffer,
. u: ], o1 a0 V( F: \+ `( O - strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));
6 {2 z* B( K# h( c, V6 @
0 M$ C/ t6 S/ z# ~- FILE *fp = fopen(file_name, "r");5 Y* b- g0 H" z; ^( I
- if (fp == NULL)
! P* _* a: b- } - {
* \: a2 U+ @! A. U7 M - printf("File:\t%s Not Found!\n", file_name); d1 @, P& J; _, {% U
- }5 R( J& w- D6 }* E! S
- else# x, x" U/ Y- H
- {$ w, L/ O- ~$ w2 b, e7 U
- bzero(buffer, BUFFER_SIZE);
& D/ {4 C; N, y) K! K) W3 z - int file_block_length = 0;
8 k0 [6 r4 T# K9 m5 ` - while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
- t, |4 Q* a' A5 E) b1 y8 P0 v - {8 O1 x# r' q/ q
- printf("file_block_length = %d\n", file_block_length);
* U( u4 k% Q" j# O8 R. P3 x - * o1 L! W% R) n$ w' }2 Z' x9 H) \. u
- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端
; w7 R5 {. Y2 n3 j, B m - if (send(new_server_socket, buffer, file_block_length, 0) < 0)
2 a" g) R: e D - {/ E( W1 n9 r$ S9 O
- printf("Send File:\t%s Failed!\n", file_name);
" U' j2 R$ t1 r - break;
7 O$ ?+ _8 k: |7 i( u4 T: ~4 M - }! F4 F* u: l; o7 G' f
- ' k+ v1 k+ m6 J( L1 H* U
- bzero(buffer, sizeof(buffer));2 G& S$ P5 t7 A7 O( h
- }
. X7 e: k1 x( o6 L2 q - fclose(fp);
+ K# z& B6 ^! O& P3 B/ f4 f/ h - printf("File:\t%s Transfer Finished!\n", file_name);9 E5 l4 \# d. r, N! }& r1 b
- }
# A. N0 N) t8 X5 M
$ {% e- O; |( t) |: I5 E6 d- close(new_server_socket);
' Y; d, i. m$ N5 J( I: b( |- \ - }
* p6 E2 f5 U; s* a8 j. K - * ^) W" t# R, w. W5 L* Y: U
- close(server_socket);# H' q! D: |. u! u6 g! g9 |6 q
- ( P6 x! U6 j) N; l, U( _# Y2 A
- return 0;: q% Y2 a0 q9 y; z
- }
2 I8 y5 F% G1 I1 @6 i - 0 A& _* v K8 V1 C S& ~" Z. L6 }9 }1 e
复制代码 ; ^+ l' J: j1 N% m" v( f
+ e$ i: W- u* D( v& V
- |0 {* P/ ?: ]) H5 V
9 L/ d L9 u- ^0 q( j; U- k |
|