管理员
   
论坛积分
分
威望 点
贡献值 个
金币 枚
|
沙发

楼主 |
发表于 2020-5-9 01:48:09
|
只看该作者
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段.) g6 ?& r& s( \6 u; t( e9 t$ k4 r5 u
- /*client.c*/) k3 N% s, ]" S: x! g5 a1 X& ]
- #include<netinet/in.h> // for sockaddr_in
- m4 h4 f+ E) `+ _2 m - #include<sys/types.h> // for socket
1 c" S$ X+ y' w1 h" i) {- j8 \ - #include<sys/socket.h> // for socket 8 z8 j# L. X1 H9 w S
- #include<stdio.h> // for printf / [) d& Y5 J* B0 e+ ~' r
- #include<stdlib.h> // for exit
& S0 |! G3 m, p; H2 Z+ G - #include<string.h> // for bzero 1 Y0 B. z. }. g
- T7 I2 ^+ Z N- #define HELLO_WORLD_SERVER_PORT 6666
. q, _5 {* R7 N& q% S - #define BUFFER_SIZE 1024 5 t) N6 P. x3 P6 s1 v8 z
- #define FILE_NAME_MAX_SIZE 512
" j/ ]& h) v+ \5 F/ B5 V
+ [8 h2 ?3 |4 y& U7 ^- k K; P8 o- int main(int argc, char **argv)
. s0 @& r# g/ v$ I+ _/ w+ u# ? - { J: i/ z6 W) e X' h2 ]. N$ T
- if (argc != 2) ! t- Z% N4 h u1 f, h
- {
9 K: f ?0 t& |/ u, | - printf("Usage: ./%s ServerIPAddress\n", argv[0]); 8 _2 ^. e& r6 k9 s% L% h
- exit(1);
7 R i8 C. ]. Q! K4 h - }
" k/ q4 P: }2 z$ N) E
+ P8 _+ z) e$ d) @; W ^- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口
4 b* O7 M$ w/ J( ^" v- ~* f - struct sockaddr_in client_addr;
0 T2 M3 N' b9 | - bzero(&client_addr, sizeof(client_addr));
1 S7 g1 ^; x3 ~; w. U - client_addr.sin_family = AF_INET; // internet协议族 ! u7 Y8 Y. Y: \
- client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址
4 f. ~/ U R3 s* @& A; i - client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口 9 I1 v+ w$ }5 c6 s( i
! \+ u8 Z: t/ R) L+ l& s! M3 z- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket
, N4 l/ ?; C! K" l: y7 ~ - int client_socket = socket(AF_INET, SOCK_STREAM, 0);
; i" D1 c8 N% T% O$ y - if (client_socket < 0) 0 n( D) P2 _6 C1 K3 u( K5 ]# Z
- { : k; {5 |+ [% I8 i
- printf("Create Socket Failed!\n"); * c6 I9 B. @3 d) Y4 ? k
- exit(1); $ x, O' b0 _2 b: G, A* `0 v: Q
- }
/ H, X1 `, k8 R4 h/ L( t
. y4 w9 k, M' k9 b" x) D- // 把客户端的socket和客户端的socket地址结构绑定 , E9 x3 z2 U n& p; w$ y, L; b
- if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr))) 1 |# Z$ J, ]: u7 p4 H, S7 B, k
- { $ y+ B0 M. w* U7 T9 ]$ }. t- @
- printf("Client Bind Port Failed!\n");
y& Y! s5 A q$ ?3 f7 r - exit(1); " Y( ?4 s8 D0 z9 q
- }
" j; W3 A8 T- k9 _* v! K
( u) A3 p! C7 q+ N0 [* p! I, b+ _- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口
! C/ T4 X- ?# P% F- X9 Z - struct sockaddr_in server_addr;
) ]; d& D$ |! m/ m$ @ - bzero(&server_addr, sizeof(server_addr));
5 U' I" d: C1 _% T/ N* c6 _" B - server_addr.sin_family = AF_INET; ) k4 {' k! j! s" v: t9 q3 V
- ) x4 z1 R& E! e! \& }, C4 [
- // 服务器的IP地址来自程序的参数
& t: f) u& n' i9 e5 a' J - if (inet_aton(argv[1], &server_addr.sin_addr) == 0)
: d1 F! n5 a. @9 h3 p2 P3 g/ K - { + {7 @1 O8 q6 \0 z3 q
- printf("Server IP Address Error!\n"); S/ [$ T2 M2 Z
- exit(1);
: N/ ~* u) s G - } 3 ~8 }" f C# L) {* U) ]
- 5 `4 y$ ?5 s% q" f8 n: E! g1 {
- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
. w) |+ R1 ~4 Z; e6 { - socklen_t server_addr_length = sizeof(server_addr); 2 k7 r1 N; b7 N
0 \, t2 @& c @5 |; {4 G- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接 8 R9 U* L3 U+ t9 D( f- [
- if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0)
/ u- O e4 z* ]/ m) {8 H - {
; N! c5 g2 w; t* m$ ^: O3 \ - printf("Can Not Connect To %s!\n", argv[1]); $ Q! Q4 o, `# C
- exit(1);
. @* s$ u% \) N( W - }
4 K& t4 h0 V, v
7 c! r6 l7 V, @) l7 h; O- char file_name[FILE_NAME_MAX_SIZE + 1]; # S" W& h4 N8 R; D% w. H
- bzero(file_name, sizeof(file_name));
1 z( Y! n4 j$ F- Y+ P5 l( g9 ] - printf("Please Input File Name On Server.\t");
9 @/ B% j# v8 }$ o, O% O - scanf("%s", file_name); % H" L1 j1 w9 }+ X Y+ W
- , l1 v% K5 O. Z$ d g# t
- char buffer[BUFFER_SIZE]; 2 O0 Z. t$ s/ M% o$ P
- bzero(buffer, sizeof(buffer)); 0 K l) M2 E; ]) p
- strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name)); 4 {1 h3 t$ w7 t+ c" T! A
- // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字
1 C1 Y- Y8 @: n* @" z; ] t; a - send(client_socket, buffer, BUFFER_SIZE, 0); 9 G; W* f9 n7 [% e8 o! W
- 0 z5 i8 X: E, Q9 | d' n9 T
- FILE *fp = fopen(file_name, "w"); / y5 ^5 a4 h& S" h; L, k) |, X
- if (fp == NULL)
8 g1 V: M L9 K! @7 G/ r - { , j6 n0 d% h; i; t
- printf("File:\t%s Can Not Open To Write!\n", file_name); & Y0 h3 ]1 X( p
- exit(1);
3 S9 q1 r) I4 _6 c - }
2 `/ p1 m. t. ]1 V8 } - & j9 V! G5 f% ?/ p$ J7 x% k: A
- // 从服务器端接收数据到buffer中
4 _/ n( U* }. K' a$ G5 t( u - bzero(buffer, sizeof(buffer)); # H& O0 l4 Q6 {! }3 o0 S, v
- int length = 0;
2 _: Z; J/ z W/ \1 z6 v& d; N. n2 W8 W - while(length = recv(client_socket, buffer, BUFFER_SIZE, 0))
" b6 ^1 Y" M K/ F3 C+ ` - { & N+ e0 T' p+ p! \: F: v: k$ ^
- if (length < 0)
% u V+ A; H$ S( J - {
! D* }9 C/ O) {/ B* x+ S - printf("Recieve Data From Server %s Failed!\n", argv[1]);
' r' k: e. w) t6 {; J3 P - break; / |/ @' w% p9 s2 O: l! m X" ]. G8 s
- }
. R' D( H$ L5 ]3 s f% I# L( E) d. r - + @; [% L3 b7 n4 W, J5 g" ]. H
- int write_length = fwrite(buffer, sizeof(char), length, fp); ]9 h# _3 j9 A: d
- if (write_length < length) 3 a+ G! |0 u$ c# S G
- { + x) p2 X, F) k5 k0 S
- printf("File:\t%s Write Failed!\n", file_name); * @: I* D7 ^8 E- v# s6 n
- break; 9 z0 A( v- x0 i" j k; u$ w" m: l
- }
8 J2 U5 H- U4 y' t( r - bzero(buffer, BUFFER_SIZE); ) j3 @( I, X0 {1 A U" r' {
- }
: n8 }# u. c! u. ` b) k - 7 v0 f2 P# ?% l* t/ L! b; E, U5 w3 C
- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]);
! t. R- ?$ w1 J9 d- O0 w$ b* ^
1 K9 U0 V. B3 }( @0 M- // 传输完毕,关闭socket - M! r+ V6 |# x5 u5 i' @
- fclose(fp);
* W0 F1 ~5 u5 D% ~; F( ]% _ - close(client_socket); $ S$ R3 K8 @- `3 Z: b+ O
- return 0;
; Z" Q! U) F7 M5 s - ) C0 l0 q" s- m) |( C5 k9 _0 I! F4 s
- }
1 { u) x6 B& y2 c8 M1 j - 2 P' W1 [6 s [! H8 Z0 t
复制代码- /*server.c*/
! s2 i1 Z. E5 G2 L2 ^& H a5 t2 ?. a - #include<netinet/in.h>
6 e- ]# R% ^8 ? H+ u. D, b8 P6 O - #include<sys/types.h>1 W/ o1 G& s5 _" L0 d/ q
- #include<sys/socket.h>7 `9 g( G! B/ F: |/ Q d" F& r5 \
- #include<stdio.h>1 R5 b I0 o! n
- #include<stdlib.h>
6 @' W. ^' o+ K/ A( T - #include<string.h>3 e# A8 M9 ?- ?( O
, z5 f/ [5 k2 W' w8 _7 h6 E- #define HELLO_WORLD_SERVER_PORT 6666 //端口号, z' b2 F& [+ @5 G1 a7 a) o' F
- #define LENGTH_OF_LISTEN_QUEUE 20
: {, B: m4 y+ ^+ U6 m$ k0 s - #define BUFFER_SIZE 1024$ U8 }, n3 y! U4 o) \
- #define FILE_NAME_MAX_SIZE 512
7 ]) _: A3 k+ O: C1 P% F2 c& a
' Z1 ?; }1 [/ n- X, U- int main(int argc, char **argv)% z: I! T+ O, V/ I0 v; ~7 S
- {' R! E7 h6 a8 v' w. M5 I5 Q# J' v
- // set socket's address information
1 K; }6 }0 f9 D s, F - // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口; O( v1 b4 a+ y; r5 O9 E
- struct sockaddr_in server_addr;: Z/ n- f3 {# |; f
- bzero(&server_addr, sizeof(server_addr));% R$ j; c- W, [ t" A% `
- server_addr.sin_family = AF_INET;& } k/ ^3 u1 o# a( T9 s
- server_addr.sin_addr.s_addr = htons(INADDR_ANY);9 t" J1 D0 b# C& U8 K
- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);: f$ w3 B; K8 x3 O' U
6 @9 o% V4 z% Y$ P- // create a stream socket
1 M7 a5 }; D0 A5 L9 p, v) ] - // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口! ^5 ~. g4 M2 [4 L
- int server_socket = socket(PF_INET, SOCK_STREAM, 0);
+ ~" P% j6 v2 P' K - if (server_socket < 0)
2 e' t' t1 b' w4 p - {$ l5 Z1 m! w+ z( R8 k5 e
- printf("Create Socket Failed!\n");
' d" o* D6 D' ]. ] S( u - exit(1);* E! w2 i& O+ T: Y( Q$ p
- }
6 W9 ^( _, G) h G8 C) A2 g - ; Q) N0 @1 ~4 E8 |
- // 把socket和socket地址结构绑定
; w1 k- K. y T9 Q; e) t - if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))% N f6 R( d, n- \, l/ ~' }
- {
, ~: Y2 U' a/ `/ f3 x1 H2 E/ ? - printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);
- C# F6 S: s# o# s) a1 I - exit(1);' Q# \9 p9 N3 b4 ?! q4 a, ~
- }- M# O0 T' `. V9 @) B
+ c" e- d, r* o! J7 I- // server_socket用于监听
# p5 O1 o" T) v+ T1 d - if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))" l# |) T' F I) T) d# q2 l
- {
7 I0 Z6 z) Q! }, X4 |; [( ^ - printf("Server Listen Failed!\n");
+ }; ~. ^9 f) m# I; i - exit(1);
m r- P/ n5 g% Z - }; [3 C0 }& J' A! j. I/ A: Y
+ G H8 C# a" U- Q; F! x/ n% A- // 服务器端一直运行用以持续为客户端提供服务
9 N/ D) M3 r5 M3 Q - while(1); c; e: D: r5 V7 Z. `/ w& m
- {8 c' ^7 V$ h" I8 g
- // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept7 B) ^- C5 z" n7 h$ d0 z
- // 接受此请求,同时将client端的地址和端口等信息写入client_addr中- K: X( m* k- W7 a6 u/ x% U
- struct sockaddr_in client_addr;$ b! w+ {% n7 ]6 g. C5 [
- socklen_t length = sizeof(client_addr);
5 O2 ]- t- [, d7 L& N& R: o
4 I; s) d$ Y0 y4 C- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中2 C4 J1 z7 [3 C' T/ ?
- // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以1 p0 K E3 x2 ^9 ^7 _$ f3 E1 {. i
- // 用select()来实现超时检测
' T9 Y* ~& w- A; |9 M' l - // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信
1 [4 X8 }+ [: ] X$ S7 M2 \3 I& _+ U - // 这里的new_server_socket代表了这个通信通道
, V1 I0 F0 I9 Y - int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);
; I6 d( B( g* k3 H( E/ n; a - if (new_server_socket < 0)
, t) D; H# c% Q$ c8 E- q - {
7 M n5 I: n% m- ^ - printf("Server Accept Failed!\n");% e* A( z/ }9 o& |/ h8 `3 l9 @
- break;8 ^) h! I$ b6 q+ F
- }
' u* a1 J0 t5 r1 M+ i3 l
; m" T/ G7 L' {' q; U3 {% r- char buffer[BUFFER_SIZE];; r# b2 H. F' j+ [4 u9 ^
- bzero(buffer, sizeof(buffer));
9 o7 T6 B5 L8 p) s' P+ T' _: U - length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);
+ K. |( D/ @5 v7 t" N5 ? - if (length < 0)
4 F6 @0 E7 c/ y' j8 N - {
; ?( M0 m2 P: }' \& H3 d4 I8 d" h - printf("Server Recieve Data Failed!\n");
, U+ T. x9 U% y- s1 B - break;
! r" U2 c1 }9 u. k8 @: w/ |) X - }
1 w) X1 r& O1 _8 H; D2 q, ~ - . Q1 I' r2 p% c- A& P3 N5 Z
- char file_name[FILE_NAME_MAX_SIZE + 1];
/ @3 s: A4 \( w9 e2 a# V8 H - bzero(file_name, sizeof(file_name));
8 e/ O% X7 D8 U$ u* @+ O - strncpy(file_name, buffer,
P' F' N2 k, |' G M/ C - strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));
( D0 ]; p2 }& J3 O: b- {( g - 2 ] P: Y, }6 P$ f
- FILE *fp = fopen(file_name, "r");
# s) ~( x! V2 H7 {; X - if (fp == NULL)
8 d ?5 A. ~5 w; i - {
) c+ [0 p( v5 m8 u - printf("File:\t%s Not Found!\n", file_name);
K4 A) w. f2 R% K) q5 v - }# N$ n$ |- X4 R/ Z+ @
- else+ ]3 p" N7 s% F$ U8 \) h8 B3 `
- {
" Z- B5 M% j& D5 T4 k! X! Q - bzero(buffer, BUFFER_SIZE);- ]5 g+ l9 P' {
- int file_block_length = 0;: m( V9 _/ O- E- l
- while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)! [+ s$ o7 F$ U' Y+ T- H
- {: K# C% ]1 S% B8 ?2 x i* S7 |
- printf("file_block_length = %d\n", file_block_length);1 t W7 O. I3 o9 P( Z1 k
- ! a8 D5 K. r3 \/ R1 \2 [/ m
- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端7 h- U1 w' c/ v, f
- if (send(new_server_socket, buffer, file_block_length, 0) < 0)1 u k5 g# b" ]" Z; X$ H |, ~
- {/ v% Y# k2 B1 w& B" Q. w( v
- printf("Send File:\t%s Failed!\n", file_name);
. f3 K( j9 c& b7 Q( k6 b& Y - break;
5 Q( [ S" @0 [2 @ - }' n% s% @( E4 a" p( _$ W
- " |4 }0 i& b! Y: ]
- bzero(buffer, sizeof(buffer));
6 z; i6 {* \; X1 ~ - }
& f$ N7 h. W; n3 Q - fclose(fp);
8 T6 x& D; o4 k @ - printf("File:\t%s Transfer Finished!\n", file_name);2 R2 d& E1 S) z3 X1 w8 ]
- }
9 N9 t( u0 t" j) H7 ]
' @# `, G0 F% T: w2 s- close(new_server_socket);2 U4 J3 C8 F8 `, p2 n
- }
# F0 r& a, A3 y4 s1 d+ I
6 s9 M( R, Z, Y: Y" g" k- R- close(server_socket);
3 f( V4 C& V" B7 }3 S - 9 X; M8 `) X; g1 K1 g1 V3 q# L
- return 0;2 R/ |- g4 K" q
- }% n+ j @, h* }- I: ~
- ; p- z' [( @4 O, d" W0 O
复制代码 ! ]. I- J* j% k5 C
( n, V( |1 J4 e6 L3 N
3 Z/ `7 p, L k+ N! J! y! p$ p# g- k8 o8 f
|
|