管理员
论坛积分
分
威望 点
贡献值 个
金币 枚
|
沙发
楼主 |
发表于 2020-5-9 01:48:09
|
只看该作者
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段.4 a/ k- e/ Y: G3 c/ R/ a
- /*client.c*/
@2 n; n* @3 x( f - #include<netinet/in.h> // for sockaddr_in 0 y$ c7 Z2 T4 l
- #include<sys/types.h> // for socket - M2 E% A5 Q- G7 I. H+ D
- #include<sys/socket.h> // for socket & f* T* ?0 G% _6 k
- #include<stdio.h> // for printf * ~- r. ~9 J @' F. q/ j$ n
- #include<stdlib.h> // for exit ; Q( r# j2 J8 l/ J' @) O- ?
- #include<string.h> // for bzero
- X0 u/ p0 Q3 G1 Z - 6 h# U' i' I a' w6 v
- #define HELLO_WORLD_SERVER_PORT 6666 8 n4 R7 K1 a+ v# \' A( r
- #define BUFFER_SIZE 1024 ( e7 T# M; x! ?3 O; x6 E. ]
- #define FILE_NAME_MAX_SIZE 512
F X0 ^% N- q& R& r! l" z, B% p) s
0 ?' P+ h9 c; L1 Q% w+ Z- int main(int argc, char **argv) ( l4 q- j; ], d4 C3 s. h2 O+ a
- {
0 @: o3 V# L2 x' P f - if (argc != 2) $ C3 B' l6 X7 x8 {* G
- {
) \3 q( ?+ Q5 z4 X - printf("Usage: ./%s ServerIPAddress\n", argv[0]); ' E! _! h: T1 l0 h) ^3 [
- exit(1);
. ]0 Q0 E( \2 z: F9 Y' H" u" V$ L - } ! B. ~9 @- M( g$ K9 u
/ \5 Q5 A( l6 g6 D' h* i' }" M1 x- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口 . u2 i' j2 N% v- w* i
- struct sockaddr_in client_addr;
, w0 F. I) J3 L2 g/ i, g - bzero(&client_addr, sizeof(client_addr)); # D4 {2 f3 U( q
- client_addr.sin_family = AF_INET; // internet协议族 ) S5 ?& v$ [$ B# w; k5 Y# G6 a
- client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址
! _3 E0 B" y4 B( Z, P! p' b' y - client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口 ( ^! }! K0 E' B7 w" w, ?+ F. w
) n' O0 {3 A/ p; X3 v( E2 j1 S- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket : {( Q8 B1 Z4 j
- int client_socket = socket(AF_INET, SOCK_STREAM, 0);
6 r" K# m. ^& ^3 m3 W - if (client_socket < 0) ! \ B+ W0 l& W b. w1 Z
- { ) j: l8 `& W0 k2 c1 d+ ~4 G7 k
- printf("Create Socket Failed!\n"); , b8 x; J5 c3 y+ d+ {% k
- exit(1);
0 P# Y4 ]# }4 J8 a4 v - }
5 Z" A( i4 q5 l- ~
' M) K0 D [1 Z- q( C0 u0 L- // 把客户端的socket和客户端的socket地址结构绑定
{/ S8 B3 H& E ] - if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr))) $ @& z3 ?* P7 o2 n
- {
& z8 U. q. \$ B - printf("Client Bind Port Failed!\n"); 8 V5 i9 _: I: J; \2 Q$ p
- exit(1);
9 O+ A+ }% g( m' J5 x - } 0 P6 G! \8 p- ~
- / r2 \- i U7 R1 W" r( U+ G
- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口 3 Q$ j- B! G# ]& |% c: @
- struct sockaddr_in server_addr;
9 H c6 N0 l) K0 v2 w - bzero(&server_addr, sizeof(server_addr));
, C& _% q: r4 W7 a# O9 T* K3 I; {* X - server_addr.sin_family = AF_INET;
9 o! q$ b8 W* A3 y+ F1 I7 I! c
' E( v9 g8 ?" `) {3 H4 ?( f- // 服务器的IP地址来自程序的参数 / {! m4 J) Z! n* R0 m
- if (inet_aton(argv[1], &server_addr.sin_addr) == 0)
- R* W( P2 J+ @4 v* B - {
; D5 W. F. T! e! V5 a- B s) [1 U - printf("Server IP Address Error!\n");
h' T0 U) e: u: K7 q - exit(1);
) I# V( {& y6 F5 M) ? - } # L0 E6 U D, E) D" e
, |; O3 V4 B. e3 M$ f" E2 R; y- t- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT); ) U6 p. K) A1 E4 N# P K/ M5 G7 O- \
- socklen_t server_addr_length = sizeof(server_addr);
: t9 w% ]8 o x4 i+ |) B" s' l% M+ I - $ y0 v$ W. _( t7 }9 ?/ r/ E- J
- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接 ' U+ O! f. t( e) ?9 d
- if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0)
" o h) C2 Y) h t! h - { 2 \0 {0 s( r2 U8 L3 d* |/ X$ i4 R
- printf("Can Not Connect To %s!\n", argv[1]); . W( E4 W/ R; G# w9 D% E, F* [0 q
- exit(1); ' K9 X9 r* i( I) A& n- s/ ^
- } + a+ g/ q9 I: x
- 3 s/ p/ a: B* R" D' K
- char file_name[FILE_NAME_MAX_SIZE + 1];
" J+ Z$ l4 [$ ]# R& Q: z - bzero(file_name, sizeof(file_name)); ! r- ~3 A: [# d2 T
- printf("Please Input File Name On Server.\t"); ' C* V* ~; o6 F, H( ~% U; B
- scanf("%s", file_name);
4 u; }, g. p3 \ N; T - 1 v: k& X: Y! G7 ]/ h& ]: I# i
- char buffer[BUFFER_SIZE]; 5 j1 W0 F' }( L1 g4 m
- bzero(buffer, sizeof(buffer));
( i4 w3 l* L0 f3 u# b+ S - strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name));
) U# g5 L! `5 J f/ r - // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字 1 H v& B2 [/ s1 Q) ^. e
- send(client_socket, buffer, BUFFER_SIZE, 0); ( { q/ o1 q% i" s
V& O- u8 E3 T# E: }+ B- FILE *fp = fopen(file_name, "w"); ! G& _! P* B3 [
- if (fp == NULL) ( r0 ~. F& G0 I
- {
' M% D3 P! z" |3 |" ] - printf("File:\t%s Can Not Open To Write!\n", file_name);
% v$ ? E' U2 E# Y+ f5 I9 C$ m - exit(1);
3 V8 s/ t; g z3 q( q5 [ @ - } / t! H( V$ b# l6 L
- , {: e% @/ z% E$ }, j7 u* [
- // 从服务器端接收数据到buffer中 ( ^" @+ S7 q. t( @6 h3 ~+ H
- bzero(buffer, sizeof(buffer)); / ~; _" i% _3 c) U1 S9 T
- int length = 0; - K G& h$ U" f' v# M
- while(length = recv(client_socket, buffer, BUFFER_SIZE, 0))
$ V! w8 C: ^& D ~8 e5 K+ d, y u - {
% B' m/ e2 f; F) v8 x' u( { - if (length < 0) 8 |' R. }7 Z8 x4 h* M9 a
- { w5 d- m5 @- d7 |8 V
- printf("Recieve Data From Server %s Failed!\n", argv[1]); & ^/ n- |* g9 N! P# [* I; T- R1 \
- break; ; q7 l @1 |0 E
- } - K/ J: G/ w" B& r
- 8 f$ W. _7 o3 J9 F
- int write_length = fwrite(buffer, sizeof(char), length, fp);
; U# T4 |5 b `6 P - if (write_length < length) - x# W- W- V/ T' O: B
- { ! n- b2 z( J5 a0 \! U. [6 u. ^
- printf("File:\t%s Write Failed!\n", file_name);
% U* l5 a* V5 c7 _; m" l) s - break;
& n, t8 G: r- r& Y9 r) S$ e4 b - } - u4 A) J- ^" b3 s# X+ m$ Y7 o
- bzero(buffer, BUFFER_SIZE); - P+ `7 u; V( ?) s( A4 D) y
- }
9 `# O% h# Z, c5 v' J - 1 p+ ^6 U1 Q( W- _+ B9 }
- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]); k5 c. g1 o( s) O4 P5 U4 i
- & M% r$ [8 m% U* R# `! s
- // 传输完毕,关闭socket
# j n* `9 ]. R) Q - fclose(fp); , o# B0 b+ L) @* A
- close(client_socket);
/ A0 I1 \/ }6 w* W/ u+ t - return 0; 0 Y# ^* ?: _& h- E9 ~6 e& c6 a
+ K9 ~7 @1 E* o- a5 H+ P& s- } % j: P/ }( u9 Z$ }3 z/ i6 k/ r( W! M
- ; Y" l9 s0 R% O/ b8 P) J3 v
复制代码- /*server.c*/* F# W* Q; N7 [2 L
- #include<netinet/in.h>
* O+ l! D1 ~' L# Z+ k. v. c% q, U - #include<sys/types.h>
( Q* K9 |% D/ a - #include<sys/socket.h> L9 @7 u# o) \$ `- p8 U; y
- #include<stdio.h> L( ?( G& p* j/ a; L% P+ p
- #include<stdlib.h>
% N7 d6 J9 P0 i w. D* V3 E - #include<string.h>5 z' M% O1 S% F# ^2 K3 L$ b
- U0 K$ R n' U( _7 k! e- #define HELLO_WORLD_SERVER_PORT 6666 //端口号7 m8 N3 w* c6 I
- #define LENGTH_OF_LISTEN_QUEUE 20* m, z8 }& y/ ~# |9 F1 D6 R
- #define BUFFER_SIZE 1024% S# |; [8 c5 a- P' T
- #define FILE_NAME_MAX_SIZE 5128 c: H1 o9 P t& ~9 r
) c. Z' b- ^1 g5 j* @- int main(int argc, char **argv)& Q5 O& C8 B& X- z+ `" B) Q
- {
# K5 z5 p U& b: i: j: |; Q! W: ~/ U - // set socket's address information
: G4 N7 N# T9 A+ s& k, ~( Y+ f* @# P - // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口/ `* w! e2 m, r1 B: d/ P
- struct sockaddr_in server_addr;$ C3 i5 l5 ~! X H
- bzero(&server_addr, sizeof(server_addr));5 X% Q/ o4 a( O7 ]/ i4 h, L0 j5 [
- server_addr.sin_family = AF_INET;
( B9 ~: s" X+ n - server_addr.sin_addr.s_addr = htons(INADDR_ANY);" ~" n7 `. f# I1 s& U0 v, B
- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);$ s6 E& F) ~' D4 c' J- k
; o; x- T* j, b' _) D/ S/ [% v- // create a stream socket
5 X5 Q9 m6 i4 D! V1 n$ J* ^ - // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口
# Q6 j9 s) h% f/ v4 C0 M - int server_socket = socket(PF_INET, SOCK_STREAM, 0);, K2 i X4 p8 n W( I2 _, n
- if (server_socket < 0)
6 |$ `; L+ }* i# Y9 X- | - {
" z! v' Z3 x$ g7 p7 e7 P - printf("Create Socket Failed!\n");7 f$ v L, W- }+ J
- exit(1);+ {& }: P: S' D, u# ^
- }) O4 a8 L* v9 f& @1 ~: u6 c. J1 {' `
2 U( b4 i O, Z# ?4 _6 n- // 把socket和socket地址结构绑定
5 g6 a' D- n$ P6 w - if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))7 _; ?; @% ]) [/ {" ]! m
- {
# X" N* N6 k7 w% i% t1 t - printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);
. v$ P- {5 y* P5 o/ I3 h7 y - exit(1);; N2 `" e* m- X2 i" m" K' e! `
- }2 u+ K1 w! j2 ]2 v
- & O/ n9 c& Y- W1 e
- // server_socket用于监听
2 q/ ^8 S! Q; A - if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))
! X; H3 h$ [6 D- k/ U8 J0 ^6 \2 W2 W - {3 F0 [9 t4 v: j# a
- printf("Server Listen Failed!\n");
+ Y& c( o" U. {6 N# n' N - exit(1);
# r, C% u7 o4 {" S$ R4 o! O' S# L" r - }/ i$ X2 F2 o+ W8 i8 C! i
% J$ o7 p; `4 R) ?" l s- // 服务器端一直运行用以持续为客户端提供服务 J) X- j8 |3 b, E
- while(1)% m2 X- i# W' g
- {; i8 m4 d6 r O% O, H3 H# j, k; T
- // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept5 [2 ?% \ _8 G* \% g
- // 接受此请求,同时将client端的地址和端口等信息写入client_addr中
8 X- p9 A4 @, @& F1 O - struct sockaddr_in client_addr;& q" p5 u/ Q& u7 }! }, ]
- socklen_t length = sizeof(client_addr);
: [+ f& W; F* d6 J+ e5 u2 z1 l0 q
' X0 `! O; @. O% W! P, M; O- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中
$ C5 d: K7 g0 f/ t1 @ - // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以6 D5 j9 V$ O/ y# g" w
- // 用select()来实现超时检测
$ @6 m) \4 T. h: M - // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信
: m8 q% o( V& i/ @7 G% Q - // 这里的new_server_socket代表了这个通信通道" u1 e3 a v+ `& |0 B
- int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);6 M$ c- o5 J) W: d
- if (new_server_socket < 0)+ P3 Z, Q$ `' _
- { @/ G1 X" X) n# p9 [- Q2 b c
- printf("Server Accept Failed!\n");
! |0 K6 B" b7 t1 @" x B) V/ V - break;
4 f3 m' T/ T! R. F& } Y' \6 F - }% P+ a+ K4 h7 F) V4 C) j: k7 j f
' T* x& F4 b f' _ |- char buffer[BUFFER_SIZE];
q' E( Y% D4 G: W% i( V2 x - bzero(buffer, sizeof(buffer));
' f$ e5 t" S& `0 a+ u* Z+ v - length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);- l" I: Y7 I" O
- if (length < 0). G+ {/ B6 G; P, j- l
- {
, v2 \/ d p$ N/ N - printf("Server Recieve Data Failed!\n");
! P$ R8 a- E9 O# w7 n2 t - break;
! a4 e4 a% v' _& h8 J- M - }
7 f- P3 M0 t e! U5 x( b# F
M) x1 f1 W$ j- char file_name[FILE_NAME_MAX_SIZE + 1];4 Z, J4 T" @& n% V
- bzero(file_name, sizeof(file_name));
$ M) {, N1 ]5 f( ^- e - strncpy(file_name, buffer,
. \! ~8 O' B& l1 S& i - strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));
* _" @6 l! w# g3 \; I1 V - $ M, ?4 \! g! r! {
- FILE *fp = fopen(file_name, "r");+ W9 J3 P4 n6 Z6 T2 l
- if (fp == NULL)
6 C: l9 y( [# |4 y - {
& e+ [- S2 q+ v - printf("File:\t%s Not Found!\n", file_name);! ]9 K2 q$ o, H M3 h
- }
! P7 Q3 r+ J9 ^; k4 T, c* e - else
% |! I6 i2 c6 [# g+ J - {) \8 N& X, I% r" d# n$ w2 j
- bzero(buffer, BUFFER_SIZE);% g# g! u4 i! o: L: q/ K2 T7 Y) u
- int file_block_length = 0;' [7 h( j3 i# M& D+ B) v( E
- while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)( T" N" Z; k1 p4 r ^
- {* o8 a$ s, W+ o0 B# ?" @# `
- printf("file_block_length = %d\n", file_block_length);
2 q8 M, s' Z) u5 ?1 F# c
0 i' }7 z, K) E: h5 C" H- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端% M6 a3 n2 j' i0 k" ~
- if (send(new_server_socket, buffer, file_block_length, 0) < 0)
1 m, i @* X% P! i6 t( U - {
3 g9 n) k4 B# U, O - printf("Send File:\t%s Failed!\n", file_name);
, o1 \- f3 r9 J; O% i# W - break;
: C" r2 \+ X/ Y5 u9 [0 |& z - }
% u* E9 v0 `. g; d - , F) K2 p/ i' J9 A0 _2 I7 P$ Y6 j
- bzero(buffer, sizeof(buffer)); B8 ] w$ ^# K+ O: L. k" B6 E
- }
7 f" i" r* U8 M/ Q' V+ E$ D ~6 t2 b - fclose(fp);
* U" C$ B* [5 T8 _' {6 \; m - printf("File:\t%s Transfer Finished!\n", file_name);
5 m% ~0 d2 m1 s7 M0 S7 r, f - }: R" x2 X/ p$ s% T: }
- * F& p- ^- t4 Z. a& C* G- u! o
- close(new_server_socket);
8 g# [9 C3 L5 o! E: y8 d6 D# K - }) {! x) f1 H! i+ V/ r2 q
- {0 N( e8 I% v7 s- close(server_socket);
- S# M5 a, i; x: i2 a- v1 p
7 I2 e7 r w X; e8 }- return 0;
# V2 n8 G$ } f4 x! S) [4 D- \7 b/ y - }
4 n3 t: e% p" o$ A6 p+ a - + i& R0 k; m6 }4 S$ C/ u
复制代码
X# I5 ^: Y- \% T: [
- V7 o# V- a6 m( v6 n* M1 c1 ^. q6 j p. ]. @) [" H4 m% E
; {" h4 _5 j W
|
|