管理员
论坛积分
分
威望 点
贡献值 个
金币 枚
|
沙发
楼主 |
发表于 2020-5-9 01:48:09
|
只看该作者
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段.
, o( H3 z/ j( j( I m6 \- /*client.c*/
T7 I2 d( `( w' Z9 A - #include<netinet/in.h> // for sockaddr_in ! Z% z( E7 X8 n- `/ m, s# L
- #include<sys/types.h> // for socket - R- `$ o9 B/ [
- #include<sys/socket.h> // for socket * n0 C! u- F5 U5 G! x& h
- #include<stdio.h> // for printf 6 g* m* }0 y+ T
- #include<stdlib.h> // for exit
* L" c+ g7 w0 e# w - #include<string.h> // for bzero
# P0 l! G, C* F& H0 k5 n# f
4 X, K8 _' m x9 M9 A- #define HELLO_WORLD_SERVER_PORT 6666 ; N8 D, S5 f3 H6 z
- #define BUFFER_SIZE 1024 G$ W9 {; F( c/ s
- #define FILE_NAME_MAX_SIZE 512
, |3 h1 z: e2 D+ K! u
: P0 j! @% T" ^" j% Z- int main(int argc, char **argv) # z/ r! a, z f2 _* t0 J. X
- {
' _& s* i2 e5 a; E: m+ _/ ? - if (argc != 2) : W0 h/ s5 u, w
- {
! L" K* d2 _1 ]1 `+ h6 f - printf("Usage: ./%s ServerIPAddress\n", argv[0]); . H8 X6 H5 c6 i( L' h/ R
- exit(1); 3 u( }/ S! D# J& {1 T
- } . v" i* c+ z8 [
- [5 H( A( p& O' v! |# d% H9 c- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口
: _* n+ ^8 k* W' @; c! c8 X - struct sockaddr_in client_addr;
) V" w7 ]) E/ Z - bzero(&client_addr, sizeof(client_addr)); 6 c3 H% Q# U1 D6 M
- client_addr.sin_family = AF_INET; // internet协议族
) G, \/ `0 ], S: t+ ~9 z. P - client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址 3 M4 B* ^7 V5 E
- client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口
8 L! i2 ~$ \3 A$ h a& P - + Z, }" p9 m0 E4 t; ?1 i4 @8 M
- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket
3 u: Q' Q7 F) z) ` - int client_socket = socket(AF_INET, SOCK_STREAM, 0);
, i/ `, F+ {- t) e4 f6 \ i' k - if (client_socket < 0)
7 q g; L0 b. ~7 `9 N/ |* z - {
& h& m5 l' F0 |+ N* @9 O" \( R - printf("Create Socket Failed!\n"); % ]" a& k. g: G1 h( {
- exit(1); 8 W6 u# r4 @5 D
- } * L! Z$ o# Q' f& u
- 1 K( E" k7 b( I. _" z5 @
- // 把客户端的socket和客户端的socket地址结构绑定
9 \. A3 U1 y. J7 n) e4 b - if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr)))
+ R; |/ j, \/ y- Y - {
9 [5 h$ F6 z) d) x - printf("Client Bind Port Failed!\n"); - l7 V7 v- V! o
- exit(1); ! K- X# C1 \# L3 {9 `- U; V
- }
) v$ v, a, @: n5 M - / [7 W" O" a: d1 d S/ ~
- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口
5 K& B$ P2 R. T* p4 B4 [ - struct sockaddr_in server_addr;
& N" V- i ^$ [+ G+ a$ K - bzero(&server_addr, sizeof(server_addr));
& M# C% a$ _+ R! O V+ ]& Z" k - server_addr.sin_family = AF_INET; 1 c+ P1 c1 e- ?& X
- ! r$ i6 J. l6 ]+ T) z) `
- // 服务器的IP地址来自程序的参数 5 S# @' v7 `3 N2 j
- if (inet_aton(argv[1], &server_addr.sin_addr) == 0) 1 U: K1 J4 h- U; \+ y. a
- { " O% z& f- X) d! L; |2 \$ {
- printf("Server IP Address Error!\n");
1 g( |5 k5 N1 z% O - exit(1); % _& P$ b/ c3 |0 D5 r/ B
- } % L. J% o Q% M+ ]6 N0 H
% w" `& l9 _8 \% E% m/ D- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
! P; @; X8 v8 |& _9 k- b; k - socklen_t server_addr_length = sizeof(server_addr); & L4 j# w# R; z8 Q% y" X
- % s0 i$ `* c% L9 E2 J
- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接
+ T" V! {2 |5 ~" Y8 h6 `9 l# E7 P - if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0) 2 F! R! R/ O; i2 C5 I4 S" l/ v Y
- { , O) s. j4 }! G r; C. h% \
- printf("Can Not Connect To %s!\n", argv[1]); # n2 }3 l9 G% I0 o- `, q# E
- exit(1); 8 U6 @. S7 \0 X
- }
7 e! }2 i" n9 U; |0 ?4 \6 E' ?
; _5 A8 U% S0 ^3 i! c q- char file_name[FILE_NAME_MAX_SIZE + 1];
' E# t% k( Z7 b - bzero(file_name, sizeof(file_name)); * t8 r! k2 h/ ^
- printf("Please Input File Name On Server.\t");
L1 _* F# m8 x. K. l - scanf("%s", file_name); 3 Q; S: V s1 e8 f% V/ U
- 3 I# U/ |( |' E% }) Y( T
- char buffer[BUFFER_SIZE]; , y# V ? d/ V9 D" Q9 z
- bzero(buffer, sizeof(buffer));
) V: P+ K7 d7 d/ |% o2 c" d - strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name));
+ S0 r) x7 x P# B - // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字 8 B- c6 X8 o2 I/ t
- send(client_socket, buffer, BUFFER_SIZE, 0); . _7 J7 o/ j% y
0 @: Y2 `, r% w& c( f3 D. A% a- FILE *fp = fopen(file_name, "w");
1 U* A" L8 U" o) _# k, R - if (fp == NULL)
4 \9 k% I) K! [/ U3 H# ? - { 6 j/ q0 x$ y h2 Q
- printf("File:\t%s Can Not Open To Write!\n", file_name); ' |- q' H- v1 A9 \
- exit(1); ; L# X* C u7 |4 n# y7 z2 v' e
- }
( G% N" f# R% N1 P# m9 x5 o - 3 }' Z9 f6 E, E1 e1 T
- // 从服务器端接收数据到buffer中 7 }9 c( {9 ? M* L( o. D/ @
- bzero(buffer, sizeof(buffer));
# m$ ^/ T4 a, D& K - int length = 0;
2 F( z: H2 W3 h- { - while(length = recv(client_socket, buffer, BUFFER_SIZE, 0)) ' g" c: ~" N( U- N! _
- { d1 w7 I$ m+ a! r7 t; `3 D3 T' d
- if (length < 0) 9 c/ I( y5 B* a q9 ?) k
- {
& Q% f D9 L0 A - printf("Recieve Data From Server %s Failed!\n", argv[1]); ' k* k& W9 c" W
- break; ) j+ s* q! z. d
- }
1 r7 u% e; B3 r$ }# { - 0 X2 R+ V7 z; v1 O0 `" t; v$ k% v8 `
- int write_length = fwrite(buffer, sizeof(char), length, fp);
0 ]0 k5 H& u& P - if (write_length < length)
2 M5 r7 G5 q3 b% H$ X8 f7 C - {
# l3 _& S; N' x$ } - printf("File:\t%s Write Failed!\n", file_name);
' v! D' h8 ?2 y5 ^ - break; 2 I0 c) V- q! _4 ^' ?
- } # x9 Q9 E" C. r6 `# L2 L' }& M
- bzero(buffer, BUFFER_SIZE);
1 H0 ^& T: q0 L - } 0 n# P; x+ a8 ?+ M7 P/ C
- ! R5 x0 y8 e' C3 x6 k2 W$ v }
- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]); 4 ? `$ @, V% e9 u1 `, p& m
- 8 Z" Y- |5 G+ m+ t8 H; N; ^
- // 传输完毕,关闭socket
4 }& F/ R% \2 P/ u - fclose(fp); 5 d- @1 y7 l# }5 ]" ^
- close(client_socket);
! d8 z( B; R: V) J' {+ u3 G - return 0; ) k5 e ]8 V7 Q, v+ c
- , q1 P$ \# ?# ~% R. `7 \$ C
- } 5 B) k) ^4 Q- i3 G/ |3 k! k% M! ?3 u
- 7 Q7 f8 [- D# y. S a) [
复制代码- /*server.c*/
" v$ v9 U7 m: ]( J" Y" f - #include<netinet/in.h>; G9 }! _8 G c: t6 p
- #include<sys/types.h>
4 a4 K7 W2 z( L - #include<sys/socket.h>& p3 V/ P8 _* C. U1 K+ w
- #include<stdio.h>
" A8 p3 A% l4 a5 N - #include<stdlib.h>
1 X1 P. K3 d/ S. T - #include<string.h>4 F! v, A- ~* ?: t% v' X
- 6 d6 l1 N4 ~4 ?: I, `
- #define HELLO_WORLD_SERVER_PORT 6666 //端口号
- L m; L, n* ` - #define LENGTH_OF_LISTEN_QUEUE 202 i" O* L8 k( H' H
- #define BUFFER_SIZE 1024
( |7 K6 o- L# {( S7 A. v U& R - #define FILE_NAME_MAX_SIZE 512* R+ e0 F) Y# w9 J' N. o
- 8 q- e, O& @9 {
- int main(int argc, char **argv)
) @ V0 y( m, `/ ^: S. c2 H - {
( `! M$ r8 D3 L# m - // set socket's address information
8 g' i: x! G! A; k; \' N - // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口2 g9 P1 A7 C- g! V' f/ d4 A( `" |
- struct sockaddr_in server_addr;) c# P. P$ ^# I2 u! i. O; a
- bzero(&server_addr, sizeof(server_addr));
8 {. ?, E3 f7 r* l - server_addr.sin_family = AF_INET;
+ B0 ?2 r! X9 B - server_addr.sin_addr.s_addr = htons(INADDR_ANY);" ]/ y1 [+ Z3 X6 B3 Q8 o# T
- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
I: e ]! h6 A- V
. O8 e. R" _. s W7 o/ a n# X' x- // create a stream socket
6 S; G0 p' R4 Z% u - // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口
" s, O+ P. l) T* O: C; I8 v - int server_socket = socket(PF_INET, SOCK_STREAM, 0);2 N& `' M, ^# e% ?, g$ A9 C% S& X/ x
- if (server_socket < 0)/ @0 i; n1 n1 Z% |
- {1 O0 d0 C: J1 R$ b! T. Y
- printf("Create Socket Failed!\n");$ r3 h' y. ], o2 S6 g; Q) p
- exit(1);1 u% }8 ~# z( H7 u7 `: Q0 f
- }1 i* u7 |+ m( u% v) n! a% L. c
. ^5 I ?: x1 z& o. S1 `5 h- // 把socket和socket地址结构绑定
& A/ M f- S% q x/ ]% q- Y - if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))6 k" h& p7 B( e, ~( \# T
- {: ?3 V7 H; o4 h- F7 i7 g
- printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);
$ P: f( Y$ y5 n* ]8 k) | - exit(1);5 W0 Q! @8 v5 I5 b2 U o+ l8 v
- }! {1 W" G; D6 _0 n) U
- ; y2 h6 T5 a1 l. Y- r
- // server_socket用于监听
% M- }/ c6 t; f S* }7 W' b1 Z - if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))
7 ]2 {! T$ e( R( W2 ?2 i - {
' z I8 i; W7 B V) e) ~4 @ - printf("Server Listen Failed!\n");
y, w* r* s# e7 e: Y - exit(1);
% a3 p0 |! V( A& O, p, P - }/ G# l, t ?, S' B
- # J1 X, O0 x1 {; P+ @
- // 服务器端一直运行用以持续为客户端提供服务
& i e& f9 m3 E8 t& r - while(1)
7 B- f$ F9 |" ?5 u$ X1 [ - {" w N$ v" w+ \8 E4 T
- // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept& V1 h2 f7 R1 n% i6 J" J
- // 接受此请求,同时将client端的地址和端口等信息写入client_addr中
* d. o9 M- L0 ~ ?; i6 g% h: F6 ? - struct sockaddr_in client_addr;# F3 K/ q9 n0 W# ]
- socklen_t length = sizeof(client_addr);* ^) X) Y& J* j: d
- $ \# P% U2 p- g, G6 ]$ B
- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中. O9 y8 m( n# w r
- // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以
2 T& X/ g# r# F3 [) C% w; i# H R - // 用select()来实现超时检测' e2 i, l$ k0 V
- // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信
% L! i( b @* o# a - // 这里的new_server_socket代表了这个通信通道8 k0 ^) n/ [# r" A* M# Y
- int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);
4 d' Z3 i& W, o+ ]3 t. E - if (new_server_socket < 0) J/ S: d. {) z7 l- n+ E! i
- {
& H: D z8 a @# H) F/ u: Z- ] - printf("Server Accept Failed!\n");8 B5 n* c. D0 U) M) g
- break;4 l$ b K% e/ w2 @/ o, X: K) W4 S0 k4 J
- }4 F: q: d2 l5 g: c- e% v# y; ~
- * N. X" N( n+ w; N
- char buffer[BUFFER_SIZE]; @& s2 @) f9 P& v
- bzero(buffer, sizeof(buffer));& a [( _8 H- ?
- length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);# e. ]3 x5 A' H& e [" q- W9 t
- if (length < 0)* B. i" U0 D6 y# ?7 Y5 s8 ^
- {0 ~, [; E# }: r% c5 O
- printf("Server Recieve Data Failed!\n");) ^ T; w) b- k$ r
- break;; N5 U* b. c7 I! e Q
- }' [. S# h! E+ a1 s, I* {! f, T+ T: }7 d
- - H$ l: Z9 ]1 j' t: c. B: J: A
- char file_name[FILE_NAME_MAX_SIZE + 1]; `" ] x: o; P" G
- bzero(file_name, sizeof(file_name));; s6 i4 x/ _& t2 x
- strncpy(file_name, buffer,
* e( {- C! {7 g# P5 f1 H - strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));
$ u6 C1 z* j0 R* u - 0 f2 {4 s# L# F* @( ]
- FILE *fp = fopen(file_name, "r");
/ d- G! M B! C - if (fp == NULL)( ` r/ p2 `2 ?7 h
- {) F8 p) _6 G4 K3 U
- printf("File:\t%s Not Found!\n", file_name);
& C4 Y5 \" o- Q - }
$ z1 R2 y# h, F; p; O - else6 Z' V0 q5 \4 M. W% ~
- {
* {6 ?# k. t) ~9 T' s% }, i - bzero(buffer, BUFFER_SIZE);4 X5 ~: A3 v+ i) E# l* C8 K5 X( R. v
- int file_block_length = 0;' L1 [' X9 c4 ~4 G* q/ B
- while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
3 e, t9 J/ F% }' j, q9 G - {
8 k1 `) a6 o1 ~: F* w) @; K. G3 p - printf("file_block_length = %d\n", file_block_length);
/ i5 f, v% a& A6 S5 x - 2 f% V7 @8 N2 L N" z
- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端
: X s( L* w6 h1 L U% a! X - if (send(new_server_socket, buffer, file_block_length, 0) < 0). Q$ q- J8 E( G
- {7 }) S( q4 [# w
- printf("Send File:\t%s Failed!\n", file_name);
! S% X4 q* u4 }/ B' [ - break;
" h& U$ J, [" N+ G - }
C6 n7 I2 w- ~# g& j7 ^! e6 O - 4 i9 y/ C; b8 T: ~# w$ [
- bzero(buffer, sizeof(buffer));5 F% w+ B% A* n/ o( g( `% e
- }- T& `. c6 ~/ b+ Q) h% g: @
- fclose(fp);
7 Q) ^( s) h# r6 X4 L% g* x - printf("File:\t%s Transfer Finished!\n", file_name);
' M8 v/ C. }+ L: w. F- D - }8 I/ w& F- b2 v8 O, M5 y* \2 l
- 3 {+ V/ V. b8 Z3 ?0 e8 j$ }5 E
- close(new_server_socket);) @$ g: K: r" q! {
- }
! Q4 _3 t& `# s9 b
: r8 `/ U: v7 |& i) I- close(server_socket);
: Z* E1 s6 R. E1 z6 z" ~. B/ w - ( Y u+ ~# H% F/ Z6 A2 x, v
- return 0;
/ ^$ q8 G* X _ - }
, \2 T0 {/ m4 I$ e, j$ h3 T q
9 F/ n3 c, r, ]4 C
复制代码
J5 h7 Q+ v9 M( v8 b/ {2 H' f# F1 a. ^
; m# z( e- w5 d+ M
* C) V! E# A: O# D; X; w9 c E |
|