管理员
论坛积分
分
威望 点
贡献值 个
金币 枚
|
沙发
楼主 |
发表于 2020-5-9 01:48:09
|
只看该作者
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段.
- q. u5 M; Q2 |2 ~1 R- /*client.c*/
. z1 Q" x( j/ ^: r - #include<netinet/in.h> // for sockaddr_in # {- {# \2 |: O/ T6 C( [3 M
- #include<sys/types.h> // for socket / S* V, H6 n. B8 n6 K' a! U+ c$ Q: x
- #include<sys/socket.h> // for socket ' r. w, z e/ P4 o
- #include<stdio.h> // for printf
6 D7 U+ Z- F7 L# o+ I0 o - #include<stdlib.h> // for exit ; [. s7 t# s9 \2 ~
- #include<string.h> // for bzero k2 r3 k8 y. f) k# ^3 A% h% ?
$ Z; x/ o% i( k- o- #define HELLO_WORLD_SERVER_PORT 6666 7 y6 v; M% q; P. u F
- #define BUFFER_SIZE 1024 # G* f6 _- p0 ?- c' x
- #define FILE_NAME_MAX_SIZE 512 1 N- p- z! j2 \* g
2 q6 B7 I$ e! P M- int main(int argc, char **argv) % L# N1 R$ A% D# h, C7 a
- {
& m% M/ w) Z0 n8 w, |$ X' N - if (argc != 2)
3 I' c" O( U9 y. Q9 V - {
5 q1 l* e( r; }* { - printf("Usage: ./%s ServerIPAddress\n", argv[0]);
8 c# O- d- x- @5 X, y# b; V - exit(1);
, R/ k7 @9 j) X; u! g4 e6 d, a - } ' o0 x; c% s7 G8 J
- & l" M6 ?* t$ j2 o! H
- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口
& d3 [; v& M a& c/ k5 G - struct sockaddr_in client_addr; 1 Z9 C2 h8 F/ ^8 K
- bzero(&client_addr, sizeof(client_addr)); 8 O6 l( N. T2 d% `) [
- client_addr.sin_family = AF_INET; // internet协议族 . o, {. G k+ m' G3 B9 v1 m
- client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址
: j7 M. P0 W% d. ^ - client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口 2 D4 f; U$ U% B+ |0 m; U
. t; T: P! u( X1 H" {- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket
' H7 A5 A& R+ A% P( ? - int client_socket = socket(AF_INET, SOCK_STREAM, 0);
& I: c1 p' y* X) v! _ - if (client_socket < 0)
- O$ E+ N" Q* C \ - {
+ ~- E1 @ ^$ f6 V - printf("Create Socket Failed!\n"); * C$ i5 A) l2 O( Q9 g. @
- exit(1);
2 Y% r! m' D( ^4 X - }
1 C, g6 {: H, V- |7 e
9 a, B( b* ~9 |- // 把客户端的socket和客户端的socket地址结构绑定 6 N t+ ~* v" _5 [9 Y! ^. V
- if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr)))
' N4 x) j) |% }6 w - {
3 G; V+ H L, x1 j; a7 T" M9 g6 B - printf("Client Bind Port Failed!\n"); . ~8 _5 [1 I, h- ^
- exit(1); / w7 e+ O# c2 ?7 e) q! S3 r
- }
' ], q1 I( T5 ?# h$ x* g
* P# r- S' x N$ ]2 Q- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口
% G; M% j! U' M! H: M" h7 B+ S - struct sockaddr_in server_addr;
( ]# c6 b) d6 B" M _ - bzero(&server_addr, sizeof(server_addr)); ]9 A; H: L- T- U- n
- server_addr.sin_family = AF_INET; ' V) K7 }7 O: _: k
- 7 x; Q; p/ p( B. N) \9 _- i2 w1 ? {
- // 服务器的IP地址来自程序的参数
; h y9 P% K" I! y- S( L - if (inet_aton(argv[1], &server_addr.sin_addr) == 0) ( t# d3 {5 |6 r |4 g) M* ^1 Q
- { , i8 |6 U' k: h0 e- v
- printf("Server IP Address Error!\n"); 3 I+ U5 x7 T E( O
- exit(1); ( t. k0 `' _% E7 ~
- }
9 T+ u( v1 {! w - ' F2 g& ^2 D L4 j- S M
- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
" L- F# s7 R4 U! b9 f( C - socklen_t server_addr_length = sizeof(server_addr);
) R) r- Q+ R. n( y% [8 K- a
" ]1 i* [# k( O- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接 : ?( a( u$ P. K/ F1 b
- if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0)
0 Q8 S% T# a9 J! w( L) }2 K - {
) {0 n5 m! {2 ? - printf("Can Not Connect To %s!\n", argv[1]); , s1 r! T, J* z+ }! |+ S+ c2 h
- exit(1); 3 i8 ~0 ?3 `1 n! I1 G3 L
- }
& R! {6 x* v5 x; L& }
5 y) M4 Q& a' r. f( P- char file_name[FILE_NAME_MAX_SIZE + 1]; # C( m6 Y7 a* k* D. O
- bzero(file_name, sizeof(file_name));
+ X! E+ j4 W" ~- Z) E& w - printf("Please Input File Name On Server.\t"); ) O1 G0 ^3 u R
- scanf("%s", file_name);
5 J8 c( f8 v4 \# Y
4 a _9 E. R" B+ N# u- char buffer[BUFFER_SIZE]; 0 |0 p# A1 F6 ?! g7 }5 I- ]
- bzero(buffer, sizeof(buffer)); {5 O7 @7 ]6 y: D2 G% ^8 m8 e- D
- strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name));
0 S. A6 l7 A4 a& T/ x - // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字
% g. b$ y" i( X2 e: V - send(client_socket, buffer, BUFFER_SIZE, 0);
( `. W' q8 D5 a; [& p8 e - 1 P/ v% M5 q# X& ?# W3 |
- FILE *fp = fopen(file_name, "w"); # W% K9 J) C# S4 ^9 r
- if (fp == NULL) $ }) t. c5 r& F" R+ q L
- {
* ]2 u) _/ _/ T( O i B" `& f* |& d - printf("File:\t%s Can Not Open To Write!\n", file_name);
( G9 v7 V6 [/ a& ^4 _7 N - exit(1);
|, e+ S" r, u |, d. o - } 7 m2 ^; K' O9 l0 s: C% A8 B/ G, w
0 D: J: e4 U( x. ?& P7 ^- // 从服务器端接收数据到buffer中 4 j3 X6 m( ?0 J6 Q8 g9 \3 v
- bzero(buffer, sizeof(buffer)); / u/ s3 w1 ?, s* v: X) h4 O/ |
- int length = 0; 1 b7 Q$ F0 r( {
- while(length = recv(client_socket, buffer, BUFFER_SIZE, 0))
3 P4 z* M% c" ]( L: I4 G5 P - {
# J3 M n, s* F% d9 C% z - if (length < 0)
) n( J/ z4 [5 Y6 `9 G - {
1 p" A( u& `% C5 w, P; G - printf("Recieve Data From Server %s Failed!\n", argv[1]); O! T0 F6 B1 j8 r# u8 a9 `. \
- break;
# ?/ a+ V: ?; r( m. C9 C% o - }
/ f+ D ?# L' C {' b0 R' @
& N. n" z- l0 G3 _- int write_length = fwrite(buffer, sizeof(char), length, fp); 3 I& q! M9 j& P8 w/ N
- if (write_length < length) : q, _6 a% p- w
- { # t7 `. O4 _, k1 k9 U
- printf("File:\t%s Write Failed!\n", file_name); 4 C9 V5 L9 m0 e/ e' f
- break; . K( N5 ]) \4 n/ N! N6 g3 t; i1 x
- }
* r! L7 K; M9 Y - bzero(buffer, BUFFER_SIZE); 0 y, Z7 \. @5 V7 u1 x
- }
; T. p3 n" ?! t - 7 f2 N& G4 r# L) j! S
- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]);
8 U) F7 k* ^/ d" m& g - 8 s% ?7 @/ Y. o6 E" w
- // 传输完毕,关闭socket * Y4 t, z/ Q5 S4 j4 b- J
- fclose(fp);
: d5 H+ U4 `& l7 P - close(client_socket);
% N' T! w# j! J$ e: c - return 0;
0 B7 H3 {. f. N% \; b; P, Z; ` - + a& z/ i: i3 E* [
- } Z0 u4 t. n- a! ~: k5 X$ g
( K/ l- d4 R: [0 E
复制代码- /*server.c*/
6 _ p7 ?4 k- ` - #include<netinet/in.h>
! p1 f5 |( Q2 `+ P8 r - #include<sys/types.h>" W/ W4 N2 d3 \: c3 F
- #include<sys/socket.h>
?3 V$ A! |# H - #include<stdio.h>4 ^8 C# p6 r6 ~; y1 {- N" h# l
- #include<stdlib.h>: u4 ?# F+ ~0 U% N% H* R9 \
- #include<string.h>
, }$ A" y0 }! o
( o& K( [0 h! ]2 @, d! o- #define HELLO_WORLD_SERVER_PORT 6666 //端口号
! E( J% v7 u9 f - #define LENGTH_OF_LISTEN_QUEUE 20
3 N& ]. \# s' T- R0 d - #define BUFFER_SIZE 1024
. g0 I0 m& [, P - #define FILE_NAME_MAX_SIZE 512! L$ ?& \. x9 O9 ?
_: H; P/ j3 J1 y& I- int main(int argc, char **argv)
) ~# ]& ] m; y( {5 J - {
) ^' q R7 A! {7 q( I/ B - // set socket's address information, g8 f- o9 R- a; L6 S, `: l
- // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口 k+ B+ U9 b* G& p+ O! T5 R
- struct sockaddr_in server_addr;
. I8 U) X' J0 z% R+ A" A( b* I - bzero(&server_addr, sizeof(server_addr));
6 _% V, u& m3 r% T5 r/ t5 _ - server_addr.sin_family = AF_INET;- T- E2 ]3 i! V% p, O0 k. L
- server_addr.sin_addr.s_addr = htons(INADDR_ANY);
5 n$ z6 I$ D4 y - server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
7 Y( }: D/ K; j5 P( c5 W" H( K9 d
6 C1 K( S+ N& O1 `) }- // create a stream socket
" o7 B8 k" F1 ^1 o0 C$ v% K7 n7 L - // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口. d- {1 c1 `. w0 T J
- int server_socket = socket(PF_INET, SOCK_STREAM, 0);
8 J8 p* L! M: ~& o0 Y - if (server_socket < 0)
9 i. l8 o/ r8 r/ B0 f! N' T3 v - {
6 l, Z, R0 \6 k" x - printf("Create Socket Failed!\n");+ L4 E7 q5 M7 p) y6 {+ y0 f
- exit(1);
6 l/ q: D! ] `8 S8 m5 k5 g - }9 }; k9 H% O$ T9 v0 @; ~% {
8 l5 l& k5 s3 q+ _- // 把socket和socket地址结构绑定' R5 S& l. A' U
- if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr))); {8 t8 [- _2 |& T
- {% w4 V3 P' N3 x1 ]6 a
- printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);
3 A: D0 z5 P$ \. Z' w- C2 {' e6 c - exit(1);! v4 p$ v, m! i. l6 T
- }1 b& G' M' V+ ]/ d
: q% w9 E2 U" }, k( i% M- // server_socket用于监听
) u+ h& r4 q' `$ a& w9 Z7 S* S: J/ I - if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))' E3 u6 G5 Y% `0 c5 y' S% q
- {
" D8 {9 x+ F3 U) i# s2 G5 C - printf("Server Listen Failed!\n");
. ?; g9 ^7 [1 g, N; V, K& \4 j - exit(1);9 W' w9 U, F9 O' ? g* H) h8 h
- }& k, J; K1 Q$ N N0 X* A# }
- ' k8 ]* ~' m( Z, U, u
- // 服务器端一直运行用以持续为客户端提供服务
% M0 h9 K# n7 w2 I3 b - while(1)
( u# P3 `& c$ ^# ? - {2 k( v3 @% _5 z) Z: H
- // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept/ d2 @) c) i, H# d. m, G
- // 接受此请求,同时将client端的地址和端口等信息写入client_addr中3 ?7 l" d( o* |- I
- struct sockaddr_in client_addr;! n# p8 t& o' f
- socklen_t length = sizeof(client_addr);, v$ b: u- g) J& @
- # G% y& N& z3 M3 o4 {
- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中) Q$ g- F- {5 j. k
- // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以
2 t& f$ K8 A5 T, @5 ]3 Y - // 用select()来实现超时检测 Q" A, Z" _) b x. m1 J8 b
- // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信
9 z; N/ f$ `- q1 C( P - // 这里的new_server_socket代表了这个通信通道0 q) S* H0 Z2 O. U+ ?4 m
- int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);7 N9 ]; n! _3 t9 C0 y. m& }
- if (new_server_socket < 0)
- h0 c4 c4 ?. b% B- c; J* ]' H - {3 [4 D/ V" e: v- F
- printf("Server Accept Failed!\n");# E+ F0 ^) w# f4 j: \5 @
- break;
1 r4 K. G4 E) E, T- |1 I) S9 r - }3 |& k& Q) g. l" C4 C1 x3 [
/ q2 ]. d: H- U- f- char buffer[BUFFER_SIZE];2 j; q# y# R% w2 w+ D. v- {
- bzero(buffer, sizeof(buffer));* V1 `7 t& ? |+ W3 \
- length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);
% q. K8 ^* Q) b - if (length < 0)
& [# t M- C" } - {- `' s! J* l8 p4 p8 q
- printf("Server Recieve Data Failed!\n");$ A- F& E5 ^) ], F% M0 z/ N3 g
- break;, P5 Y/ I0 T! H+ |
- }
* L! c0 c6 N7 r0 I; Y# }# _
( e u9 l+ h8 n% o' K+ f! s- char file_name[FILE_NAME_MAX_SIZE + 1];
4 P; x6 r- P0 s( B+ G( s( i - bzero(file_name, sizeof(file_name));
% |5 I4 g" z- D4 [8 ~ - strncpy(file_name, buffer,
5 X8 l" U& _, ]- W5 Q* L/ l - strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));
0 n; |8 N$ K0 R( W3 u' d' A* m t - # q) b1 f" l8 @# ~! k
- FILE *fp = fopen(file_name, "r");, e# c9 L# I! t+ O1 a5 T0 S* _ U
- if (fp == NULL)
- v3 b& W4 D3 G5 C1 c% `, Y - {
& Q. u" P/ B; G/ d t% l - printf("File:\t%s Not Found!\n", file_name);: v+ p& m$ t3 P1 R; q
- }7 ~7 r5 T1 r, v9 J
- else9 n: k' K0 v0 r2 k8 m5 h3 X
- {
) I5 U# B) i) i - bzero(buffer, BUFFER_SIZE);
/ a6 S+ k6 y0 T6 |& X+ `' x- W. R - int file_block_length = 0;8 `/ m& n3 j+ Y+ p
- while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)$ s6 e8 Y7 P/ s' t: S6 f6 J& r
- {0 R9 h6 I; G o5 }
- printf("file_block_length = %d\n", file_block_length);
2 D7 q' F, t- c: p, i
6 M s( A5 j) M; W& ?+ d3 L) ]- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端
) N5 k c. Z) n9 ^* U) v - if (send(new_server_socket, buffer, file_block_length, 0) < 0)4 [% v: F3 _' q7 N% W
- {
3 \9 a l9 n; O) n; g- i - printf("Send File:\t%s Failed!\n", file_name);' j$ j' \2 P9 x. L1 L' f
- break;
# y& l3 P! l' E2 q3 C - }, Q! |2 q. r% R7 @/ k/ b- m0 G W w
- ; a: |+ |. i/ s W1 u a+ c7 d8 L
- bzero(buffer, sizeof(buffer));3 e* W1 p2 l3 f! U) d2 Z6 V
- }
& Q* B( F0 N3 q& U, d9 E0 ] - fclose(fp);& i" s* G. @% Y ^0 `" C
- printf("File:\t%s Transfer Finished!\n", file_name);- J# y$ x" d, H, l. g1 J
- }
" U! s& U C9 W: |: F
7 X! W* k, L( M3 x4 Z- close(new_server_socket);
1 a9 s' k/ H R( x2 {# |4 w6 P6 S - }( m \& v4 G" ~9 T' k0 [
- 6 O; ]9 s J: Y3 l) G5 X! F) T
- close(server_socket);( y/ B* j5 g) t/ H8 G7 |' o
- 7 g6 L4 b. z5 v* k) B; l
- return 0;
: R' u- k% O: A! R2 e - }
$ D W1 Y: ~( C
: p. h5 @' Z6 _5 l
复制代码
- A% W1 W+ e3 w4 \- O# A3 ^) Y! I5 g
/ V8 `; B0 p5 G/ r. a1 P, @) X, ~/ m# V e1 D
W4 T0 a7 k3 D4 l( A
|
|