管理员
论坛积分
分
威望 点
贡献值 个
金币 枚
|
沙发
楼主 |
发表于 2020-5-9 01:48:09
|
只看该作者
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段.
& y [; v( }. ~5 r9 U$ K; @, q- /*client.c*/
* i: D; Q. D- l. E9 { - #include<netinet/in.h> // for sockaddr_in
* K( C( u2 F# s3 Z( p V2 v0 F; Q y - #include<sys/types.h> // for socket 2 E- z$ Z4 ?4 j9 ?
- #include<sys/socket.h> // for socket
9 l5 ~+ N, B, i1 N# n+ s - #include<stdio.h> // for printf
_' Q1 |2 l$ ?. {$ G4 c - #include<stdlib.h> // for exit
# m: _/ x! V2 X( ]* B5 q+ |, V - #include<string.h> // for bzero - v- `( s) m7 \# P
- : g$ z8 J {0 I6 f
- #define HELLO_WORLD_SERVER_PORT 6666 6 c' N0 c( M6 g# j' h B7 t
- #define BUFFER_SIZE 1024 2 W2 K. n/ m- x" k% I7 Z; c
- #define FILE_NAME_MAX_SIZE 512
: ] M2 X, I0 a) z- F$ C - ; F! q; e$ @4 }5 b5 Q2 ~( R
- int main(int argc, char **argv) . o: M! D" z' A! i" u9 `
- { 6 y5 l) N; V6 s) l; ]
- if (argc != 2)
. _# l/ D6 Y5 C# r - {
0 \5 n! c5 q" F- z. C - printf("Usage: ./%s ServerIPAddress\n", argv[0]); % w, \- \8 E; T3 P
- exit(1);
& h: _. ]$ ? M3 b$ ~, b3 ` - } 0 h$ B# N1 q0 J4 ^" p
- L/ H, p7 C4 k1 o' V# \& M- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口 9 ^) l$ v; ]! b
- struct sockaddr_in client_addr; % s% Y& j* l2 a( R
- bzero(&client_addr, sizeof(client_addr));
% Y& E2 c4 Z Q: X: ^- t - client_addr.sin_family = AF_INET; // internet协议族 * s0 U7 q" K" E& J0 {; U" A4 |. s+ \
- client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址 / J$ L3 Y$ B2 m8 H3 W K, P
- client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口 . }: m5 `" x+ E) G3 g. B( X
# g: V4 B8 s* c5 x1 f8 x- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket 5 G4 r( _# q6 h; k( ?5 |. l+ R
- int client_socket = socket(AF_INET, SOCK_STREAM, 0);
w) n4 y/ I) Z0 t - if (client_socket < 0) / O1 S* c% r8 T
- {
$ F% |- m# K2 G' }# c - printf("Create Socket Failed!\n"); 2 v9 P# v6 @; \' u: r2 K/ [
- exit(1); 9 C. {& H: r4 ]; M5 G
- } : w- F$ E2 s0 o
$ e! e+ m9 f2 ~, X* [- // 把客户端的socket和客户端的socket地址结构绑定 8 X O" o8 Z _5 H* I$ S
- if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr))) - o2 z; i8 I% Q1 G/ s
- { % K$ @4 h2 V( z( Y9 e1 j$ ^3 r
- printf("Client Bind Port Failed!\n"); 6 O7 q' g2 K6 ^5 R, ?6 Q# @ u1 e
- exit(1); $ t. p' d5 F" ?* [; h, t# w3 k
- } ( N' ~8 e( V/ G4 |9 \+ i
- 7 y' M4 _( a0 p
- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口 2 T/ p1 P; @5 j l3 V
- struct sockaddr_in server_addr; ( K7 p8 w* z7 C9 b6 T3 l% O9 r
- bzero(&server_addr, sizeof(server_addr)); $ t9 l$ y' U$ |; c# Z4 Q8 o/ s% m
- server_addr.sin_family = AF_INET; 9 d" P& E0 ^' X6 G, j6 z- ]- k
- % s- U; N5 ]$ g8 p) V
- // 服务器的IP地址来自程序的参数
: \0 @2 J) f4 |. f7 c' ]: B- b" ] - if (inet_aton(argv[1], &server_addr.sin_addr) == 0) + h' S' D# Q) n- v4 V0 X+ [' t
- { ' \3 f$ M+ }& i! R
- printf("Server IP Address Error!\n"); - ?# B( P1 O5 I2 l
- exit(1);
, u& i) I; o$ \' z - } ; S( _7 k* Y. `. z9 ]; X
- + r+ [% H7 r( N* R+ p
- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT); % q9 D% U! z, l% q
- socklen_t server_addr_length = sizeof(server_addr); ! Q. f5 L$ E$ @+ U$ o
- % o9 p* ]1 r0 ]2 L% s4 ?
- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接
" j/ [, k/ w8 E( k8 o* |7 i - if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0) * e _( ]5 P I: }$ m
- {
6 B" X8 N; z/ w$ {( x9 ? - printf("Can Not Connect To %s!\n", argv[1]);
" H; ?% r" c; J3 y - exit(1);
' `6 F) B' [+ N3 z& r9 g - }
- k* k" }5 Z7 \9 K" f9 q& E - ! z6 H8 R3 r* N: {, E
- char file_name[FILE_NAME_MAX_SIZE + 1];
8 c! @1 d, ?+ w' k& z - bzero(file_name, sizeof(file_name)); - x7 [5 Z# |# J; y4 ?6 ]" ]1 }8 J
- printf("Please Input File Name On Server.\t"); & Z7 e+ e! Q/ X! i
- scanf("%s", file_name); 3 r% [+ d0 r6 r+ J
- 5 X; R+ l* y9 I7 S. S2 q
- char buffer[BUFFER_SIZE]; 5 [9 ?& g2 o/ c5 R2 z
- bzero(buffer, sizeof(buffer)); ( t& r# @4 Y* U9 C* k
- strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name)); 0 |8 A2 Q. n; }: ?
- // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字 4 R. R: `8 o; T, ?! l1 f/ R* }
- send(client_socket, buffer, BUFFER_SIZE, 0);
# Z4 I2 ^) x% d" N - 4 V# ?, {) O$ x- b: w5 e( ~2 n" t
- FILE *fp = fopen(file_name, "w");
' D! A2 [7 T& s5 w# A - if (fp == NULL)
6 I& r) t2 S, v- _% U9 @' D - {
, s1 [0 Z0 o" m - printf("File:\t%s Can Not Open To Write!\n", file_name); . a9 z7 n5 {- q3 Y! t: `
- exit(1); 4 [1 I+ A3 K+ z& g
- }
! f1 Q! @5 I* j8 [* D, n0 N
+ y- _+ u4 w+ ^& ?) i; p- // 从服务器端接收数据到buffer中 2 x0 W; _7 p8 {1 O) M/ G, u
- bzero(buffer, sizeof(buffer));
: R. }% g' m* [6 E" S4 N0 S - int length = 0; 5 `& D; K: N3 }9 B' w3 K* b. i
- while(length = recv(client_socket, buffer, BUFFER_SIZE, 0))
0 N0 Z' w3 |7 [6 Y Y3 v - {
! J5 S0 ?1 E% E! ^ - if (length < 0)
; B0 }: O; [/ H1 {0 d - { $ b6 j" q4 C. `: b/ b: \% q
- printf("Recieve Data From Server %s Failed!\n", argv[1]); 6 i* L+ l* c2 T" S6 Q
- break;
: U* ]1 h5 S& Y: j7 N$ `/ C" A - }
: F4 w' [( ` Z0 c7 @' x - " E$ h3 Z! e6 A( L6 u( z* G
- int write_length = fwrite(buffer, sizeof(char), length, fp);
0 O6 r' b w' l2 r8 d - if (write_length < length)
2 C6 X& q/ |5 p( `- z/ ^ G# {4 ~ - {
3 ?1 O$ e. ?* l+ j - printf("File:\t%s Write Failed!\n", file_name); / e: `7 C7 @0 T9 ]4 p
- break; % C$ o/ q1 U" g" h) u! C' n3 a
- }
+ t+ W. r! p; f! _ - bzero(buffer, BUFFER_SIZE);
' l' G! n- N" H- j6 } - } + D1 t/ i% Q E2 F
: ?( X- X5 T6 Z9 A- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]); / F: u# O* M) x
- 5 L9 T/ ~( G5 m2 D4 x0 \
- // 传输完毕,关闭socket
8 N# a3 H, k7 _" ` - fclose(fp); " n Y( C9 S/ b3 e
- close(client_socket);
8 A8 ~/ s% U1 b/ Q/ }9 k - return 0;
2 ~/ P* S' O, V% H% s; Q - 4 k+ n' m4 a6 l% I9 x
- }
' D/ M* J3 V( F
/ e& a9 U- G ?* s4 M* v# `3 N1 N
复制代码- /*server.c*/
7 u3 s. ^; e J& y/ ^$ n - #include<netinet/in.h>
, q' {7 i1 N& v' ^( R! R - #include<sys/types.h>
: U9 E5 Y' U, c6 Y6 Y8 | - #include<sys/socket.h>
2 t' X4 b* F% l( R$ C0 y - #include<stdio.h>4 ~2 f4 f' V6 r7 o2 o
- #include<stdlib.h>
4 U. i' t4 {' ^1 y - #include<string.h>: I* M3 e! Y1 M( ]7 Z
- & Q# D# Y/ [7 S8 T% Z% i
- #define HELLO_WORLD_SERVER_PORT 6666 //端口号
5 k- k3 h* g- W7 }+ ^4 D0 c - #define LENGTH_OF_LISTEN_QUEUE 20
0 C! G1 @# V" f0 T$ @4 D( v - #define BUFFER_SIZE 10242 W7 c6 B1 B: f( b4 k* m( y
- #define FILE_NAME_MAX_SIZE 512# R+ |" d. d" }2 ?% N( C0 ^& w& n
- / c3 |# N. u( r/ _ R- A$ \* L2 @
- int main(int argc, char **argv)' i1 M1 w! d6 k, R
- {% k0 c2 {! M) P
- // set socket's address information! [& N2 L$ R5 Z% m; w6 p
- // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口& [1 o2 J U$ y
- struct sockaddr_in server_addr;* v2 j: H2 E+ t9 B: [
- bzero(&server_addr, sizeof(server_addr));; W( v3 g( V+ l* q0 s
- server_addr.sin_family = AF_INET;
6 e& o6 j2 B! k - server_addr.sin_addr.s_addr = htons(INADDR_ANY);) q: U5 A0 L4 o) Q9 V
- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
# _! h J( m( t3 T# m P
% O" k! |1 t O$ a* O+ d- // create a stream socket% K+ ?) l u' T4 s" Q/ ^( y1 k
- // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口
. x, v& O7 A* O3 L: i- J( T, U0 t0 w - int server_socket = socket(PF_INET, SOCK_STREAM, 0);
, n9 E7 W k/ D3 ], R1 | - if (server_socket < 0)
1 D& N8 L" G) \- @8 |' f# f/ ~8 F - {
. F1 q6 d1 r' \6 h - printf("Create Socket Failed!\n");
& t1 F4 o8 S) |- e - exit(1);
- g2 b/ A M3 @$ t7 ?: y) n. K - }; N a2 x/ a% H$ J
: I$ J5 `/ Y0 I3 b5 P# S) W- // 把socket和socket地址结构绑定3 F7 d0 x: j- x3 a+ i
- if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr))) U4 {8 C7 W ^9 e4 d2 e8 p$ g& [, M8 p
- {
5 \6 |" u' T% ` - printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);7 m( t( E9 f9 U& p) g( D$ b: `
- exit(1);" y7 e6 O! w( A5 s, n
- }
% r v! B( B% ]6 i% p/ H, H - / l5 {! Q; I# ~
- // server_socket用于监听6 ^ D N! c; m# D+ W
- if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE)). S( n4 @3 Z/ ~- C
- {
+ f2 P# U$ K9 ]! L. Z4 O - printf("Server Listen Failed!\n");
9 z* Z p' g) b1 @# E: d - exit(1);
. i' d; U6 {4 I: ?6 S1 B - }
, n, x1 P" ?8 Z3 b1 z: q/ p
& X$ C0 C9 q3 Y8 T/ @" A: O- // 服务器端一直运行用以持续为客户端提供服务$ C% ]4 J# c6 w( K' n& c5 R
- while(1)6 f1 g# @9 P2 ^) Q3 Q
- {
& Q6 ]& [" s5 d. ?, m' C - // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept: X: t! {& q$ t' r: n8 s
- // 接受此请求,同时将client端的地址和端口等信息写入client_addr中
6 h( V2 k% q/ m - struct sockaddr_in client_addr;
% O+ b! U* ~' G K$ U1 y - socklen_t length = sizeof(client_addr);& T0 _- X7 ^, y
- / I" E6 q! [0 H6 ]( U8 q
- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中
! J% k9 g! u l$ L - // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以
* s) ^9 ?2 F. B - // 用select()来实现超时检测; P' b8 S# [* M" ^1 A: `) g
- // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信$ P% L% \9 Y0 z' N8 o4 }
- // 这里的new_server_socket代表了这个通信通道" c* }, O2 L- B8 n4 s3 J
- int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);4 I" t4 Y& J: _: e) a
- if (new_server_socket < 0)( V& e/ t6 }; u$ U' I
- {$ W7 S' L$ W( k( n: M" w
- printf("Server Accept Failed!\n");
i. `' M" Y. s2 y( E% p - break;# [2 D: c5 r, R7 p3 R8 t/ E
- }
8 B8 m( W3 ?4 M0 R8 }+ u$ K& r
4 R5 v7 ^8 N/ i- char buffer[BUFFER_SIZE];4 B% }. }, U% v- f
- bzero(buffer, sizeof(buffer));
( s9 z) x0 i, A/ Z3 T9 r: P9 r - length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);
' {7 e* M, @- j! H+ I N" X4 I. w - if (length < 0)5 N w; T; j7 |. o0 M9 g& a' `3 H; |* o
- {
2 O/ v+ g+ K# v' Z8 H- C - printf("Server Recieve Data Failed!\n");
1 i" k. G% x8 J' `( K - break;
! r4 N/ F% z$ C$ P* @4 |! H - }
2 m# j2 [5 K2 p# ~) A1 C& L: ~ - - b; p0 M, m+ R. o# u) |
- char file_name[FILE_NAME_MAX_SIZE + 1];
; Y% C2 }* d- _ - bzero(file_name, sizeof(file_name));, E% I% p* l/ _( I3 O5 w( [* y! N
- strncpy(file_name, buffer,! s( a6 x1 b6 s& N2 ?
- strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));0 O" r' O( G* A+ E
- / p$ x7 L: \- e! m
- FILE *fp = fopen(file_name, "r");
6 }& f! ]7 Z3 v+ b; D! s0 K' z - if (fp == NULL)
! _. B/ W) ?4 w- L$ B - {) o# w" W$ R4 L- N- N1 V
- printf("File:\t%s Not Found!\n", file_name);
# Y2 O: R( W. h* A4 @2 R1 k5 j - }
8 Y H' b/ g8 a. k- C8 D9 r5 l - else
& o" R3 ~% t0 R - {
" X5 l1 |$ ~; s( t - bzero(buffer, BUFFER_SIZE);
0 H& g- s; ^: r K - int file_block_length = 0;
" q5 U7 x: e) e8 a5 J% e# \. a6 o( Y - while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
! y: D# i2 ]7 {$ n$ n/ P5 R$ E - {
. | x- e x" C7 E3 I& d - printf("file_block_length = %d\n", file_block_length);
+ _: C5 f- s$ w! I5 k+ Z
3 K; `# c. ~ n- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端
& A! }: | K& z - if (send(new_server_socket, buffer, file_block_length, 0) < 0)4 x% T" Q& d# a- o5 @
- {' y6 C( Z" f" u. V) P# U: w/ K
- printf("Send File:\t%s Failed!\n", file_name);
% i) d( [$ N% y" V( o* P - break;: U/ l% o4 f+ }
- }: k" q- G9 ? J, @1 J
2 V/ |' L$ ^4 K L1 m1 C* N- bzero(buffer, sizeof(buffer));# @6 p. ~! U H) O- g: [
- }
n5 h; R+ [! ^) d - fclose(fp);9 V5 R Z7 ~- h9 s
- printf("File:\t%s Transfer Finished!\n", file_name);
, Z" [, a$ J! k; _ - }8 Z3 H3 J5 l& s/ Z
2 R( s* A& f [, E) D- close(new_server_socket);- y" `( r6 T# ?( i. q6 G4 @
- }
$ X2 M4 c3 N& `4 Y2 G/ r) ] - ! B& H7 \4 m$ L1 u
- close(server_socket);
, \$ Q, W( `' T. h - & x( ^8 T4 N- u. l4 O5 f
- return 0;
% ]% S+ q( ^7 j& x; q$ J0 o - }
M* V% R; R2 ~. [7 z% u+ q - ' O9 t* O' @; C8 D
复制代码
- g+ \$ B1 _' ~' Q
% d+ H, [2 `- l1 C
- @* B2 W2 A& Q' ^& O. q1 \
9 r' ]4 ]' r1 _$ P: e: G |
|