管理员
论坛积分
分
威望 点
贡献值 个
金币 枚
|
沙发
楼主 |
发表于 2020-5-9 01:48:09
|
只看该作者
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段.. f' f* }' F! l3 r+ ^; X2 X6 m8 q; U
- /*client.c*/
M/ H [+ {- J+ u4 `9 E# w+ j4 _ - #include<netinet/in.h> // for sockaddr_in
4 D) K6 L7 m/ ^4 e& V; H( e9 Y - #include<sys/types.h> // for socket , c. D/ ^* S; I
- #include<sys/socket.h> // for socket
* p! _- Y; R; x- a8 y - #include<stdio.h> // for printf # w( {( Z" e. \% |& a
- #include<stdlib.h> // for exit ' F4 N8 h8 J+ }" f" C! u( Q
- #include<string.h> // for bzero
Q) l; x% z8 m
' q3 p3 ^' P- b1 A- #define HELLO_WORLD_SERVER_PORT 6666 4 p' w# h. s3 G. X% X) P
- #define BUFFER_SIZE 1024
/ \; p1 s( N1 A - #define FILE_NAME_MAX_SIZE 512
* j# B- V& Z( t5 q% s$ S% y
7 I7 m5 t- c# }9 q" C9 i- int main(int argc, char **argv)
; \7 d' v2 p. j1 Q - { : t; ?, V' h; H) \
- if (argc != 2) ' f$ t& D2 J, G2 |1 |" ?1 n* }
- {
) H3 R* m$ Q7 D, L5 _& ~4 } - printf("Usage: ./%s ServerIPAddress\n", argv[0]);
$ f/ v2 R9 J* P- k - exit(1); ; I6 s5 {' R$ O- h" Y* Z. U2 E
- }
: W/ b7 \9 N) O- j1 u
- z7 ?6 x4 e8 t9 c1 P- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口
' Z: z8 K" T/ \: x - struct sockaddr_in client_addr;
+ o" F+ N5 r& l5 Y - bzero(&client_addr, sizeof(client_addr)); / C' @4 O9 ^" Z( ~& v$ O
- client_addr.sin_family = AF_INET; // internet协议族
" ~& O/ K Z/ L) l7 j& s( f - client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址
0 T, B! {- N4 o; D2 d6 R2 p5 D7 B - client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口 ; S& J1 j; u* L( Z" {5 N
3 w) e, s, R; J* ^0 P# V- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket 8 P1 |7 V% A4 E9 }' O
- int client_socket = socket(AF_INET, SOCK_STREAM, 0); , x1 L* G; l% n! h% E. f
- if (client_socket < 0) : w! ]/ B1 H4 w. Z& U9 Z
- {
5 h7 k7 }5 x) [2 t - printf("Create Socket Failed!\n");
$ E9 X$ d0 t+ [6 e# {0 B4 ] - exit(1);
$ [) |+ M3 Q& K - } % X8 h, F8 Z, k' V7 r" Y: P7 @. ^, E
; B" t& v2 n9 w+ B8 g- // 把客户端的socket和客户端的socket地址结构绑定 $ b" ]# F) Y) L0 F9 n z0 J% y: g# r
- if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr)))
4 L* c, x: @$ L+ ^: } - {
: I5 @+ L& n+ d. Q - printf("Client Bind Port Failed!\n"); / z# o, R3 i/ j- w& U6 X
- exit(1); 3 e, |% k% K0 T1 b8 X$ p/ [6 `
- } 3 m0 F( c* D( k0 a( M8 Z( a7 v
- - m* H) ?4 Z' J+ ^
- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口
% V' k$ x/ d; W: r - struct sockaddr_in server_addr; 4 ^, w2 M- i t. ]4 m1 c7 c3 f
- bzero(&server_addr, sizeof(server_addr));
1 u, a9 {$ g" S% _ X/ E& w! u - server_addr.sin_family = AF_INET; % j @$ D* Q' ?. E( R5 X
, n8 @5 t* a V5 o( `/ r' l- // 服务器的IP地址来自程序的参数
8 L& h4 Q3 S4 C - if (inet_aton(argv[1], &server_addr.sin_addr) == 0) % A, A1 V: |3 G a
- { ) \7 F, M2 y% J- k( [5 U
- printf("Server IP Address Error!\n"); - I* [5 ~! \( ]3 Y% M
- exit(1);
; @0 `( T9 i2 q$ d4 N8 G7 r - } ; { w" _, w* u) \2 U; f
6 R: l! N( \& ]1 _0 ~- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT); 0 Z( r) v$ \0 j" z+ v; e
- socklen_t server_addr_length = sizeof(server_addr);
I* o- F( V9 I2 o- t$ X; ~ Q
6 n) f1 o, J/ }3 F l' {0 m- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接 % Y% B% g% i, C( l* e
- if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0)
0 D' x5 W6 C( r# a/ D# U' E - { 1 ~2 t0 o* n( A& a% H/ H
- printf("Can Not Connect To %s!\n", argv[1]); ; ^: I B6 [: ~% P# x( \" B0 P4 s8 ~0 E
- exit(1);
( G0 O9 d x" Q( ^ - }
2 c* k, M1 J* {' `+ M2 @' }3 z
4 ^/ k* o) ~& a/ }+ O0 f H1 X- char file_name[FILE_NAME_MAX_SIZE + 1]; 9 q* {4 w" a8 F7 |
- bzero(file_name, sizeof(file_name));
1 ?& ?: p# E) L& f. _6 f. ] - printf("Please Input File Name On Server.\t");
$ f6 G% |; G7 s; t/ Y+ q( F - scanf("%s", file_name); 1 y, M% ^, z3 y0 @
- 8 z" b) |; Y E: A
- char buffer[BUFFER_SIZE]; 8 n2 p8 f- O" ^5 X4 v4 f
- bzero(buffer, sizeof(buffer));
/ F% U& T X( P V* W. O7 H - strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name)); , F; P, }' K% [$ {% U3 T
- // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字 ' N7 B- N8 S7 D/ F
- send(client_socket, buffer, BUFFER_SIZE, 0);
# b6 F1 X* l1 v! n - - W) N6 B6 U! V, R. U' _) D/ `
- FILE *fp = fopen(file_name, "w");
; t& L/ R- V. Z A - if (fp == NULL) : S4 ~ @5 d9 P
- {
@ D) H) w% t# }: a7 b - printf("File:\t%s Can Not Open To Write!\n", file_name); 5 `( ^. d8 p* M- j, d1 u6 X% A' t
- exit(1);
7 L2 q$ @ E7 r$ Z! O [/ j - }
$ _( s- F. l) p$ X
: d! @! y/ P$ @* T* b- // 从服务器端接收数据到buffer中 ( A( J1 {* T% u g
- bzero(buffer, sizeof(buffer)); 1 y& v! J* r8 m1 w+ Q
- int length = 0; & k6 w8 B! n, P
- while(length = recv(client_socket, buffer, BUFFER_SIZE, 0))
6 B7 L7 p2 t0 y" l G) k2 Q - {
# U5 ?, ?7 G# T5 G o - if (length < 0) & R* e8 ? K4 R: `
- {
- d; `9 I8 A6 y; I2 N - printf("Recieve Data From Server %s Failed!\n", argv[1]);
3 \- B& u: ~1 m; ] - break; 1 E6 Q7 v/ Q P! G
- }
( w' U- m# a- `1 O
( H ?. m3 w; k- int write_length = fwrite(buffer, sizeof(char), length, fp); # I5 e; e* g) B! N2 t
- if (write_length < length)
4 {, ]5 w7 z- }* v# X. V - {
4 z4 T: J! V5 ~$ U2 S Y - printf("File:\t%s Write Failed!\n", file_name); 2 m4 F6 _5 i1 M$ }6 ~( s
- break; J) B" O/ p6 x0 K+ M
- }
c7 ^, ^- F, ~2 c. K! F4 I - bzero(buffer, BUFFER_SIZE); + N9 i2 Z% t; P6 t B# H; j. H
- }
W' _. w# ^/ _/ C' G7 Z. [
C+ X: P3 J! ^- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]); & U" q1 T8 f' s( t
- ' O$ \; p0 r& G: B( L
- // 传输完毕,关闭socket
# W _2 Y2 Q* O: b, x - fclose(fp); ! l0 v6 E' N1 }
- close(client_socket);
3 A7 y; B. q" `' b) e3 |( ] - return 0; 3 J: ^4 o8 ?: g: t# r$ y
- . E( g5 K3 A1 R9 d x, `
- }
4 O# j/ @) ^8 e
( C+ `/ m2 j9 Q: A
复制代码- /*server.c*/
" D0 \" ^& ?9 Z7 S7 V& D1 n - #include<netinet/in.h>9 Y/ q, Y8 v3 r; F0 F$ |$ J
- #include<sys/types.h>
. ~% E m2 R( A1 ^# d - #include<sys/socket.h>
4 z) I( {' c$ i* C8 a4 K+ M - #include<stdio.h>
$ B8 c8 `$ E( o3 t4 l8 N - #include<stdlib.h>; T' B6 }/ ]7 H( |2 u; p, o4 C
- #include<string.h>
5 Z, D! X, e$ o7 @/ I8 G, Y
6 k5 R; P, j, @9 d. ~$ c: |9 ~- #define HELLO_WORLD_SERVER_PORT 6666 //端口号8 Y. _8 ~- i$ R' T1 z" ]9 k
- #define LENGTH_OF_LISTEN_QUEUE 20. K/ U. t7 Q1 [+ N
- #define BUFFER_SIZE 10241 W3 v+ O8 t, a1 i1 i) d4 N( Y
- #define FILE_NAME_MAX_SIZE 5121 {4 o5 Z* v% o% P1 |5 g
- 7 }" L# Q# B$ L' P* q2 D5 A& |
- int main(int argc, char **argv)
# p v% x, [/ [, P( ~6 T6 C4 [ - {0 @3 C' _) ~6 P, v
- // set socket's address information; E3 ~/ E, M( e( y3 i. G
- // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口
) Z' g ~7 H, O% r0 ` - struct sockaddr_in server_addr;9 o3 L% W( l+ {7 g5 Y5 p
- bzero(&server_addr, sizeof(server_addr));# a* } z0 P2 k& k: u
- server_addr.sin_family = AF_INET;2 t* P- ]2 @$ }% {8 l# K
- server_addr.sin_addr.s_addr = htons(INADDR_ANY);
" r6 C8 {* }% {8 y+ V+ K - server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
* ~8 b( ]: J2 O# H+ I3 D/ E1 J
6 l* Q: O9 g; w1 Q, L) F( | r0 Z- // create a stream socket
$ g9 b H8 E( M5 I2 }0 N - // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口
2 h9 R# G1 _$ I - int server_socket = socket(PF_INET, SOCK_STREAM, 0);1 H; c+ P+ a3 h) O) @% J
- if (server_socket < 0): d( t' p, Z) B+ A/ e8 x' N$ |$ r0 j
- {
# f% V3 I* n$ x( z/ ]$ P - printf("Create Socket Failed!\n");& h5 D9 [8 ~! z
- exit(1);* H) u) E/ v) ?6 U
- }6 P1 L5 e6 ]0 W( [( t- [3 B
- ) z1 O b& B% [- |
- // 把socket和socket地址结构绑定
% ~1 {- v0 p& Z; L1 Q; V5 `+ U9 }. { - if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))5 ]% b- a9 x% T4 X' |5 v/ L/ [$ j, a
- {4 B k/ p- t2 r2 B% w: `. S
- printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);
" Q6 a$ k8 Q" v# T - exit(1);
! r2 C! n. K. S - }
5 N( C0 ~2 H) S! ^' ~7 { - R1 t3 {, l1 g. L- ^0 n$ v9 p! N$ I
- // server_socket用于监听$ Q) G, t+ o# v1 K5 ~! @0 X) M" y
- if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))& @- c3 R1 a' i: \
- {
9 c- `/ c& Q& E) O2 ]8 q - printf("Server Listen Failed!\n");$ c, ~. F& K9 R, z; N2 r
- exit(1);
2 Z: U) L6 J7 {( s" D# s - }& t9 N2 m5 S8 \7 U3 r
* N* [. d; {* x" X( N5 h- // 服务器端一直运行用以持续为客户端提供服务# U2 z7 M' j5 n: ?( B4 H1 N7 B2 k
- while(1)% W" ~3 a, T7 q2 ~
- {
5 H; G$ @# ]# t& T" b8 O/ Q6 b, s& ` - // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept) o# y( k3 |: O/ [ P
- // 接受此请求,同时将client端的地址和端口等信息写入client_addr中% p% A2 q; n: a+ ]. |
- struct sockaddr_in client_addr;
/ i+ u7 u7 s' v K, j) P - socklen_t length = sizeof(client_addr);: g, B0 w+ F! g# D+ j; G% b
- 1 O" W, e! @- J0 N
- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中
! F) E6 o) R' B0 m/ Z7 b" S8 H - // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以
( D' S: ]: P. }1 q$ Y - // 用select()来实现超时检测
0 O& c& Y& U- |" y% m, W# J$ w - // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信
* v% P8 Y0 o) m* O, R* s5 ] - // 这里的new_server_socket代表了这个通信通道
& x6 I6 y; k5 O3 n, @8 _ - int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);* d2 E9 s0 h9 k4 ]; t
- if (new_server_socket < 0)' E) Z. O; ]: X" Y. k( s% X6 @" [0 i
- {& \# Q. ]' b* P! o( F' r! N o
- printf("Server Accept Failed!\n");
$ @4 }5 W. P# i9 f - break;
4 l1 F: V+ `4 z8 Z* E - }0 K2 @. O8 j! C- `
- * l5 M b! q1 U' G
- char buffer[BUFFER_SIZE];- ^- h2 i% y3 K2 L
- bzero(buffer, sizeof(buffer));" v: I! ^! N) Y3 G1 G
- length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);
3 [7 z" o" }- D% X5 c9 _/ R - if (length < 0)1 a* \$ I5 c5 x$ U
- {+ g" p/ G2 {( ?- u
- printf("Server Recieve Data Failed!\n");
( e, \& k1 j; h* q/ M - break;' [: c& }$ c- S# e% }/ x
- }9 k& q) W- ^- m6 U5 a5 M3 S8 G
- - E9 H R3 H0 }# J4 w
- char file_name[FILE_NAME_MAX_SIZE + 1];
* l2 s# h! H' V - bzero(file_name, sizeof(file_name));5 [% O; p* T- r8 _6 l2 [/ J* U
- strncpy(file_name, buffer,8 s( j4 ` p/ d8 O
- strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));" o7 ^& s2 F/ _! U- Z- _
- 2 i2 A8 _' J# n, U$ \
- FILE *fp = fopen(file_name, "r");0 Y. W6 _9 l/ [; w# }2 L4 f
- if (fp == NULL) `) b) Q7 M9 i; M; B3 r( Q
- {
# S$ @; @8 |9 y, t4 a1 y - printf("File:\t%s Not Found!\n", file_name);. r d4 T: v3 C' q8 W
- }. j8 J% M7 {6 r% `
- else
- m5 ?/ y4 r3 O - {
/ J$ r' y/ X! ~# V8 N - bzero(buffer, BUFFER_SIZE);
9 C: e9 Y g" G. r - int file_block_length = 0;
; Z. R2 K! N6 S6 [+ }$ u# l - while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
9 h Y) @/ K5 _0 C8 W/ A2 g6 O - {$ J2 I1 s5 O) H' F" C
- printf("file_block_length = %d\n", file_block_length);
$ s( f9 i7 x2 O( \0 ]" p& O4 _
H; C& U' y# f* i9 N- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端! B2 B3 u1 g, V" v5 W' J- d) n
- if (send(new_server_socket, buffer, file_block_length, 0) < 0)+ X: @0 k; V8 q
- {
/ D( n1 ]5 ~, N - printf("Send File:\t%s Failed!\n", file_name);
7 {7 `% S! C4 b - break;
! ?2 V$ _4 f- ~0 ^3 v @" S5 u - }
9 Y# z, U1 `& E' M$ M0 W1 N - 0 k& c: r/ v8 P5 I6 |
- bzero(buffer, sizeof(buffer));
0 [1 x( n" Q7 _8 F3 @' q. l - }& [; K H) m _3 {2 M) `3 g H
- fclose(fp);
2 n8 m9 K3 V, O7 F1 p - printf("File:\t%s Transfer Finished!\n", file_name);3 \* Q. Z$ Z- }
- }
- S. H3 i" E7 k. e5 Q `
1 d! |! h9 ~ @$ k0 s% t- close(new_server_socket);8 w; i J+ T" R9 l A7 Y% u
- }
/ I" V! u3 h- X5 h9 h
- \7 ~) h& A! I; |& K1 m8 r; Z1 c- close(server_socket);
, F& W P4 n0 [ o2 i( _ n1 {
& p6 H4 s/ |, c- return 0;
5 Q) E, s7 y, u4 e - }3 E& U6 B: I0 f# N. H
- , p* S# |6 j; `
复制代码
5 y, W6 d5 h" n/ P7 c. g" ~2 N' i" C: w. z/ z# ?* z5 q: S
# t/ o% M6 u4 O3 P8 R
8 @! m* l5 k- o, _% @ |
|