管理员
论坛积分
分
威望 点
贡献值 个
金币 枚
|
沙发
楼主 |
发表于 2020-5-9 01:48:09
|
只看该作者
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段." T: H2 M( @5 j4 b
- /*client.c*/
5 C' E: W9 q' y# \( I* N1 O - #include<netinet/in.h> // for sockaddr_in 1 w. E8 |! W! Z- b5 M. w: l
- #include<sys/types.h> // for socket q" w9 [. S) d
- #include<sys/socket.h> // for socket
" q1 w/ E- K% N6 Y - #include<stdio.h> // for printf + n. {8 H0 N+ T
- #include<stdlib.h> // for exit
7 D! |6 C0 K# E! f2 o8 ]& {; W7 l# o% h - #include<string.h> // for bzero ' y: v# z3 V) }! a7 N j
- 7 v; d- {; y! X" i! P, u( K/ Y
- #define HELLO_WORLD_SERVER_PORT 6666 1 ?3 G' ], |8 P3 V! x
- #define BUFFER_SIZE 1024 4 O. C, y: k" X8 C0 S% A3 y B _
- #define FILE_NAME_MAX_SIZE 512
g3 o1 ?) k. ~3 | - 6 y8 n5 @' b5 S# _$ U5 H
- int main(int argc, char **argv) : s$ j, S @6 U+ b4 o% E8 D g0 u# F
- { " r. W3 d5 z7 X8 P$ l) B( ]' I% b
- if (argc != 2)
, a+ Z0 I1 X2 ` - { ) J$ B3 B# t! ]6 P
- printf("Usage: ./%s ServerIPAddress\n", argv[0]);
: h2 v- R ]9 C4 b7 X - exit(1);
' J4 E5 ~: {+ _7 K* b# m - }
) I J* E7 W' P% m# z - + s4 q" u- g, }& @) I4 F
- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口 5 ~3 z- h4 D" j I
- struct sockaddr_in client_addr; " o0 O2 @. y" v4 A$ c4 O
- bzero(&client_addr, sizeof(client_addr));
* t2 h$ Q/ S s. P K! ?8 b - client_addr.sin_family = AF_INET; // internet协议族 ' z- A3 |1 M7 R& J0 H2 U/ ^
- client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址
; X+ Z6 f3 z# J, I1 l" D, u - client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口 * j! e7 x8 |7 y; R, D+ i- H$ H/ \
" p& {5 O8 y) d1 L% o- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket
: L, W8 Y" b3 U7 L2 ], ?, T& J - int client_socket = socket(AF_INET, SOCK_STREAM, 0); 7 G. ?" n& k8 z3 ]# {$ ~2 [
- if (client_socket < 0) 4 S' K7 D( F! V' e, w+ S0 u1 s
- { " K4 G0 b) @7 {
- printf("Create Socket Failed!\n");
% }/ R, M x1 q* k6 F& Z* P - exit(1);
# _$ _) f0 D& G+ ^$ c - }
( {# y: c4 j9 G+ e) ]& o! v j - 5 H8 W! p3 j& I4 G- t' L
- // 把客户端的socket和客户端的socket地址结构绑定 , M- X7 B5 a! O1 ]
- if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr)))
% W) a, T( m: Y ~ - {
: G6 f' s/ |; z% Z! e - printf("Client Bind Port Failed!\n"); : c+ b% r5 A1 h" G% T6 M$ \) Q. [
- exit(1); . g4 Z: j! B: b8 S- ]5 Q0 p
- }
" h# u Y7 R* Z6 g; }$ T. h+ u
. \9 x k, V p! c- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口 ' C7 X: h' x: `# {6 Q8 x
- struct sockaddr_in server_addr; 3 q+ Y. }: b: v. y
- bzero(&server_addr, sizeof(server_addr));
; ~. H4 I- |8 I7 ]1 |9 @; q - server_addr.sin_family = AF_INET;
" h3 F& f" `% }: [
+ N9 {6 N2 \- _6 _; t9 e- // 服务器的IP地址来自程序的参数
! J6 s+ j* Q; d& [) I) u# l" t - if (inet_aton(argv[1], &server_addr.sin_addr) == 0)
5 p& ]/ U- A8 G# ?6 y8 q3 k9 v) |' @6 _ - { 7 {& L2 k" P5 g$ m: N8 {% \
- printf("Server IP Address Error!\n");
: `: q n6 a3 ^! Q" H! ^+ X - exit(1);
( ^ `4 l4 [' ^+ E1 {4 ~ - }
! D: J( Q# r' _' @# j8 V; ] - 3 a+ N1 u: T& j3 d
- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT); & ?7 f/ l" I# I/ J* a9 J& y. _
- socklen_t server_addr_length = sizeof(server_addr); . {/ f; U- M+ Y3 `: ^$ e
- ( ~: s1 j6 B$ [ r
- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接
8 D0 ]/ P+ K. P8 _! c. Z - if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0)
! Y" L# T* m, j1 s1 M4 s - { : _# n" R8 o& m5 n
- printf("Can Not Connect To %s!\n", argv[1]);
4 ~$ k/ f5 d. Q. F0 g% F) D R3 X - exit(1);
( @* {$ Z' d+ I - } ( `* j% D# q ^- n- m
) ]: S7 m6 h% L8 z. e- char file_name[FILE_NAME_MAX_SIZE + 1];
0 P i0 y- _3 V7 L; Q - bzero(file_name, sizeof(file_name));
4 ~1 T. [% _/ o9 {! g8 Y - printf("Please Input File Name On Server.\t");
9 H# T; U# {% s) D/ i7 B: A - scanf("%s", file_name);
1 P) s/ Q X% a) `
2 O; h- @5 e* w* Z- char buffer[BUFFER_SIZE];
7 s/ Y4 f& [) I' i - bzero(buffer, sizeof(buffer));
. s; i7 B& k7 s, F - strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name));
3 }, t) r* [2 |# d5 u- \/ x0 J9 z - // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字 & ^7 b$ N/ J6 |0 J
- send(client_socket, buffer, BUFFER_SIZE, 0); + ]' t0 r2 Y' m: l( T" {! _
- 2 U% r3 _2 }1 e. j9 S* J8 X5 H* U
- FILE *fp = fopen(file_name, "w");
( f! s, E7 G& A$ C - if (fp == NULL) 7 F1 Y) |: C. O6 p# P
- {
# ^$ B6 A4 y: D7 V - printf("File:\t%s Can Not Open To Write!\n", file_name);
9 _, X0 S( C, H: }4 J - exit(1); / f1 I8 v5 |" a( t
- }
3 c* g, d, m/ ]/ H
% ^0 ~; B! ?8 Q3 f* C7 F- // 从服务器端接收数据到buffer中
8 \' ^) j. P. w' G - bzero(buffer, sizeof(buffer));
4 q" c p: Q9 L; n5 J - int length = 0;
- I C7 K$ G+ C2 o N: D1 C - while(length = recv(client_socket, buffer, BUFFER_SIZE, 0))
& Y# Y$ L* a- q* q - {
* a5 l1 }, v9 P* x6 G) u6 ~; F - if (length < 0) $ s5 s' ]5 e: L' W7 b! p- L, A
- {
4 x. F4 X3 f3 u( B4 ^ - printf("Recieve Data From Server %s Failed!\n", argv[1]); % f+ p6 I, B; N0 S1 n% I7 K
- break; ) z4 r" r$ ?& L' j! ^+ f
- } $ T+ X& y* u- H9 U* k; k
- 3 d# L4 w+ P3 O
- int write_length = fwrite(buffer, sizeof(char), length, fp); $ ^1 N& H: G. n7 k0 V' k/ N0 t
- if (write_length < length) ) q3 g' e0 p' c7 M( ^
- {
- C0 w1 _9 ]) x/ q8 Q/ u- a4 e - printf("File:\t%s Write Failed!\n", file_name);
6 [% d; ?& G" I+ V - break; 2 U" ^3 y8 ]: n4 `* v8 g# f
- } 1 \4 G. j, v8 m$ J& F
- bzero(buffer, BUFFER_SIZE);
) X4 `/ Q% ]; G& R) I - }
1 c o, u: x3 h/ @5 f - ' C& _* g: T3 K( _% X: P, a
- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]); ' g l! F$ D; G% D
- ' w" [% s. T* t7 [6 }: }4 d& `
- // 传输完毕,关闭socket $ R6 G' Q* v$ w$ J9 n# v6 l
- fclose(fp); ' I8 D4 R1 }9 c: a
- close(client_socket); 9 Y$ ~; |% S6 q) F9 d
- return 0; 3 h2 r4 s7 a' Q# F( C0 B7 A! G
6 I# a7 E, w" y0 w. z- } $ z7 Z1 S" {, |, E5 u, ?+ S6 P
I; m8 _! ~% O- X4 _& g
复制代码- /*server.c*/
& V1 O2 M; R, j% }7 ]+ \, v+ @ - #include<netinet/in.h>/ r. R' b$ A( k
- #include<sys/types.h>
4 M- g# k' X$ H& j - #include<sys/socket.h>" J2 D+ v: F3 I! U/ x
- #include<stdio.h>- O$ k" P0 k7 S- o
- #include<stdlib.h>, z. K! z9 j" N D
- #include<string.h>5 C8 w/ s8 q9 P: Q/ K, J
- U5 T/ o3 G1 d6 l! [- #define HELLO_WORLD_SERVER_PORT 6666 //端口号$ f& ^; {: [1 S+ C
- #define LENGTH_OF_LISTEN_QUEUE 20" ?$ O% Y, o+ h7 q- A" A
- #define BUFFER_SIZE 1024
) h- b% B4 K/ `2 B, y - #define FILE_NAME_MAX_SIZE 512
! S! U% m& x! [6 B" q7 \) f - ( }) T5 @3 r \2 `
- int main(int argc, char **argv)4 N$ [; W+ V5 R7 N' V5 b( ?
- {% C* ]8 F' x2 }) u
- // set socket's address information
9 W% O6 R7 Q) M - // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口
- S9 q1 P" @( e5 _ - struct sockaddr_in server_addr;( t( a, D. V, g9 [. J3 B8 Z" V( ]
- bzero(&server_addr, sizeof(server_addr));& d2 R {, Q3 ], C
- server_addr.sin_family = AF_INET;9 W+ w6 r4 Q- j! R' E
- server_addr.sin_addr.s_addr = htons(INADDR_ANY);
- B; g5 R4 ~0 o' O& q3 c4 E - server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
; r8 ]% w6 c% Q4 ?% T' E: D" i
/ B& ?. ?/ _ b2 c- W6 z- // create a stream socket8 M! z( _" b# I
- // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口
0 B f# v- }3 h, }3 J - int server_socket = socket(PF_INET, SOCK_STREAM, 0);3 J6 M8 H- t6 A* i$ P% A* K
- if (server_socket < 0)2 Z0 S' u5 X& M! ]' y
- {! U3 \" {, X. ~
- printf("Create Socket Failed!\n");
* ~) Y: m" o5 d! E6 j' T: I - exit(1);
?9 I! w0 H+ l6 V - }
R- I8 I4 B! q# m
0 y' w$ i# ?. U- // 把socket和socket地址结构绑定! k$ O# r: H, P* p
- if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))
' X" ?9 t1 k( S0 y/ \ - {
8 ]& [: h! n/ a5 d6 b - printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);9 n& V0 ~( M$ C- j4 J. T) D
- exit(1);
6 O% ~+ I: F' Q7 j2 `5 B% Z - }
6 H* p6 _0 {1 }+ a" `2 V- L - 8 h: W: A3 p; Q. J9 l/ Z
- // server_socket用于监听
7 M- _6 @3 n, `: P! A6 ^7 B - if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE)). r- f# g M) i9 V
- {2 t6 R" E4 h1 Q* M
- printf("Server Listen Failed!\n");5 u5 i; ~6 D! p9 [6 |$ @
- exit(1);- V8 O0 A7 C# b* {5 _2 H9 w4 ~
- }+ g" t4 C( d% T$ a/ e/ o
- 6 ]+ ]& Z- j. z
- // 服务器端一直运行用以持续为客户端提供服务: \6 [# ?$ T& C0 G% i5 j# c$ b: E
- while(1)8 K. F+ F$ p4 K2 Y: N
- {4 W* U. c% P; Q* S$ |
- // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept5 w- v0 o$ Y; K# W k
- // 接受此请求,同时将client端的地址和端口等信息写入client_addr中, E, }7 X8 f- V
- struct sockaddr_in client_addr;$ X' Q+ g- J( |
- socklen_t length = sizeof(client_addr);
$ V6 `: @( z" s# X2 E3 E - 4 z$ b1 U$ b) d5 g4 `. R9 N2 U
- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中
/ l" @) T$ y. D - // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以! D: w. K9 o- S/ |/ m
- // 用select()来实现超时检测. O. h0 t& p1 `& e1 C9 h; t
- // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信
$ ]) _2 Q3 w, C/ k7 { - // 这里的new_server_socket代表了这个通信通道* J; T3 w) _ P8 R* R4 Y
- int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);
; E g$ i! b1 V2 q - if (new_server_socket < 0)
7 {- p9 w e7 ]$ P4 R7 I3 q" _2 J3 P P - { y9 `8 d# {0 D8 I1 y3 j% v- d9 e, _
- printf("Server Accept Failed!\n");' ^. D# R! L0 `" N/ L8 S: T
- break;* p3 c" {3 Z& e& j/ f" A2 F+ j
- }
! t# ]+ M* n+ d2 q3 b5 X - + y" a/ s6 r+ f* ?5 Y/ p" T6 k
- char buffer[BUFFER_SIZE];( g; Y* \, E' [" C
- bzero(buffer, sizeof(buffer));4 i( ]$ ?0 |9 O6 G6 c
- length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);6 w U1 T0 w( x8 \: V
- if (length < 0)0 E) C+ h! g2 j4 B( O
- {
1 `6 H- k' {4 c$ i: y; X. o: k - printf("Server Recieve Data Failed!\n"); R* {' T' k* ^
- break;! g( R! p$ c4 z7 x# R, Y
- }. X5 y) O: N7 }
+ `7 [7 y! L) ]; u+ o( ]+ z- char file_name[FILE_NAME_MAX_SIZE + 1];
* t- V/ V" J L- y+ F5 J8 Z - bzero(file_name, sizeof(file_name));
4 M# G; |3 B& {' Y" N$ O8 i - strncpy(file_name, buffer,' q6 p$ s% S. J5 b! Q* x6 r
- strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));
& f6 V5 W4 q/ D1 O8 v+ l; R( S
" x/ z% p: @! R) y0 E% J- FILE *fp = fopen(file_name, "r");7 k" i& f3 z/ U! b1 ~
- if (fp == NULL)
/ R: _! N* S W$ W$ i8 E' ]0 Y - {. K' {/ E8 r% i' q: Z7 c B
- printf("File:\t%s Not Found!\n", file_name);+ G2 K6 [4 q& ]! S* _/ |5 j6 `
- }; d& s8 g5 k) e7 Z
- else
# J1 i; W" S* B B, ?; K- h - {8 J6 ]6 \5 e6 z/ C- Y% j! t4 F
- bzero(buffer, BUFFER_SIZE);
& L' p* h1 \' R# }) l - int file_block_length = 0;6 o4 N0 V+ [/ A% F$ u" C
- while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)" v5 _- F2 b8 {4 O1 Z
- {
+ l! h. M* c/ n! i% y8 h - printf("file_block_length = %d\n", file_block_length);
( F2 U) J4 X: k- K$ h6 g - , a4 f) T! S% S, j
- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端
1 c$ T( M8 ?- W8 \1 B7 O - if (send(new_server_socket, buffer, file_block_length, 0) < 0)
5 O1 c) [+ ^# p5 Y4 B - {" M, q% w" Y2 J) m' a( s: h
- printf("Send File:\t%s Failed!\n", file_name);" `8 K) p4 ]# g9 f6 f: d D
- break;4 G3 L7 ]4 v+ B* V
- }
+ V; Q$ C2 V7 ]$ M+ f w - ' e- R& Y% H; w# r
- bzero(buffer, sizeof(buffer));
- f/ Y3 X: q q8 S' Z - }
& Y% ~" L+ y7 w1 F, U - fclose(fp);
9 y' l( ^# P! \7 T' n+ E. C - printf("File:\t%s Transfer Finished!\n", file_name);
9 e0 P, r( R1 a& R - }
. j1 r6 V' y, ~! i2 Y - ) ]: @5 n$ [4 [7 f. \, n8 ~
- close(new_server_socket);5 q1 N% T- q' p+ H( M' g
- }
* C" b$ N T( E" P6 h
; G$ t4 D! Z8 z. C, U4 r- close(server_socket);
* b0 A# Y% H$ E; s4 M - # Y& O& K: @ e6 w6 p- M4 N" k2 T
- return 0;
) ?( P: ?1 _6 G8 j- f0 N' | - }
6 ]8 Y8 S+ G0 D- K* @
6 {( {. Z" U! ], `9 d" v
复制代码
8 x$ K, \. b% d& l6 W0 K# W! }0 `" F& K" f3 W5 k
2 E3 o, i& N( k$ s4 B
% ?3 r' _: A! r0 A! I6 @! ~( ` |
|