管理员
论坛积分
分
威望 点
贡献值 个
金币 枚
|
沙发
楼主 |
发表于 2020-5-9 01:48:09
|
只看该作者
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段.
/ T, M. C% v6 x- /*client.c*/0 y; ^. G4 P. g
- #include<netinet/in.h> // for sockaddr_in 8 n' [6 b0 o- h0 z0 [5 Q
- #include<sys/types.h> // for socket
8 y5 i( S5 M8 H+ m- S2 g) Y7 A - #include<sys/socket.h> // for socket
T0 k7 `9 b5 |9 | - #include<stdio.h> // for printf 5 p7 t$ L8 A0 y* `" O% D4 A2 \
- #include<stdlib.h> // for exit
" S0 x# Q; J1 z* ]: c - #include<string.h> // for bzero 1 u5 L/ N p# {
- ' Q* D `$ F8 @
- #define HELLO_WORLD_SERVER_PORT 6666 % ]5 K' d* q# F+ j3 h% e/ h
- #define BUFFER_SIZE 1024
# E, d; U5 B" B" L, @ - #define FILE_NAME_MAX_SIZE 512
. K! u8 V9 x- x) p5 U8 d7 V' z, ? - ; V; R2 T- L7 X, C* y$ Z
- int main(int argc, char **argv)
" @5 Q5 F1 R9 j; o* n - { ( K, ?2 x) [% W8 u0 a, j
- if (argc != 2)
5 a9 m$ E* m6 u: X0 H+ M% i - {
, s' D' W- b4 O* W" ] - printf("Usage: ./%s ServerIPAddress\n", argv[0]); : U- ]+ o' ~# ~ i5 f: n# ]
- exit(1);
3 B1 V( B. {$ v6 d: w - } # Q7 P5 |( v( _7 O+ i
- 7 O3 `$ m+ T( b
- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口 9 H& X- y# d5 U! K
- struct sockaddr_in client_addr; & `# i. Y' O2 o, F$ w6 q3 `$ m$ Q
- bzero(&client_addr, sizeof(client_addr)); - S! X+ b6 ~ Z7 c1 F+ P8 ~; R% D
- client_addr.sin_family = AF_INET; // internet协议族 # R8 J% u8 w0 f/ n
- client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址 ' Y; f! b7 b' }. c* f% `/ D& {4 w
- client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口 ( m/ B- M( S. j3 A4 u! L% c' B
- 0 ~ \6 b2 y c5 U9 w a% h
- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket 8 E3 a: p9 o) d j& v5 N6 @
- int client_socket = socket(AF_INET, SOCK_STREAM, 0);
6 g8 b& j6 [6 D - if (client_socket < 0) 4 M% v. N+ @0 [1 X' ]
- {
- D0 H8 p# e, e0 |/ {4 S9 v - printf("Create Socket Failed!\n"); 7 p! f- ~- Q. t( W
- exit(1); 4 k9 G9 ?, \% s y2 q7 ]
- } / e9 ~* G2 C$ e
; ]9 Z9 Q# `' v1 o* B E, e& p- // 把客户端的socket和客户端的socket地址结构绑定 . w4 E. @" c& |( Z
- if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr)))
+ L" m" F, J$ B8 z - { 0 {" R4 E$ E! T5 K& ]7 J' l9 H, A
- printf("Client Bind Port Failed!\n"); # X4 o) g7 @, {5 Q+ {+ C9 a8 z6 M7 |8 D
- exit(1); ' h! c6 t: `- Y" M
- }
5 m) k/ W. B3 u* O; O - 8 {( u4 e, v. T, p2 c
- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口 5 J7 |; u" \- d6 U- e6 M% K
- struct sockaddr_in server_addr; 4 U4 l" I2 f% ^6 A) F4 \7 O+ w+ C7 X4 Z8 p
- bzero(&server_addr, sizeof(server_addr)); , [# B, z" K" V' F4 l! w
- server_addr.sin_family = AF_INET;
: k5 z' N* W7 e
$ H- r' n: y* B# ~7 k* d- // 服务器的IP地址来自程序的参数 ! `# ]* k; i& R. Q' ?" H. h l8 W
- if (inet_aton(argv[1], &server_addr.sin_addr) == 0) ' T4 x/ o. t6 p W! e. I: V
- { - ^! Z9 J4 v8 f* G
- printf("Server IP Address Error!\n"); 5 W2 Y# u! B, E7 J4 w) [
- exit(1); 5 Y( K u% D8 ?* w0 @
- }
" P# S$ B5 Q. c4 ]
7 K( u: g7 Z; C7 m, M0 N- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
, [7 q8 e1 p! a6 ]1 c. U( ?1 t - socklen_t server_addr_length = sizeof(server_addr); / G7 `, T: R1 g3 O9 f
* k# H3 x- d" T V) i( U- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接 , ~3 d; m' b% |8 D
- if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0) ! {8 g. ?6 \8 Q0 s" s' B2 Y* g6 M
- {
- e! I7 ]) a. L1 ]/ R+ `' ` - printf("Can Not Connect To %s!\n", argv[1]);
8 Y7 `8 K# K; g - exit(1);
- v+ a5 M5 G0 W/ R - } * b: U. l$ ?% Q# B5 q) t, _
- q0 n9 r6 y' R, {" S& u4 E! Q
- char file_name[FILE_NAME_MAX_SIZE + 1];
) n" F2 l/ u2 X3 a- { - bzero(file_name, sizeof(file_name));
' o* t; ]$ \; G* v - printf("Please Input File Name On Server.\t");
& j3 [! o: L3 J4 P7 L8 Z% w Q - scanf("%s", file_name); 3 Y V- S8 w& k3 j5 i' b
- : D' g! N5 W8 e
- char buffer[BUFFER_SIZE]; B$ S# S3 a% p- x" G; B
- bzero(buffer, sizeof(buffer));
: S, g& |1 h, r& F6 B x& ] - strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name)); & f( V; ]. d: U/ ]' Z
- // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字 + [/ M) m! @& L B
- send(client_socket, buffer, BUFFER_SIZE, 0); / y% h$ W* [+ H$ ^
3 n( i/ J$ d; q- FILE *fp = fopen(file_name, "w"); * x* H5 e0 a/ H* r3 j% x0 k
- if (fp == NULL) 1 ?( u) G) Y0 X' w
- { + ^# M6 g( S7 n Y' e
- printf("File:\t%s Can Not Open To Write!\n", file_name); ! Q& m* }1 B/ O0 j
- exit(1); 6 S$ i! |9 K! }2 o
- } ' } [& d+ y# A) z2 y- B+ ]7 { W
- - L6 q& ~# x6 ~4 O9 V
- // 从服务器端接收数据到buffer中 2 ~" ^3 m8 N$ q# y$ M
- bzero(buffer, sizeof(buffer)); ! s5 R2 T; F) @, X! D Z ?4 c
- int length = 0;
' v2 Y2 F9 V) j/ n - while(length = recv(client_socket, buffer, BUFFER_SIZE, 0)) 7 M: `$ m2 K. a k+ n7 ?4 u: U
- {
/ o* r2 t2 N/ \ - if (length < 0)
' a% d$ q3 g. G G - { 6 ~# g1 \$ i7 d2 H9 d- _7 |
- printf("Recieve Data From Server %s Failed!\n", argv[1]); $ ~' r9 h: J/ o' Y
- break;
/ i: @" v: ^& c - }
1 S) O# U% @4 G9 a. K/ \) o9 F4 `
/ T7 r" \& ~8 ^9 |& V- int write_length = fwrite(buffer, sizeof(char), length, fp); 0 S& g' U0 C" ^* d7 G$ j) {
- if (write_length < length) " X2 E/ T( V; \9 {) t& ~- p+ Z/ Y$ S
- {
6 w$ e) _4 R6 g8 q, B. @" m - printf("File:\t%s Write Failed!\n", file_name); + q# ~( S) P5 A5 ?4 X2 O" p
- break; ( G/ I7 b; Q; K2 k, @, ^
- } * m& g7 \ a' X/ A. ~* Q8 o- W+ j% ]
- bzero(buffer, BUFFER_SIZE); 8 `6 v: ~# i7 o% K2 x
- }
& `- B! {/ e( x4 j" T
; v1 a v, }, t- j3 P6 W- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]);
- | q+ V, z6 w5 a- w* B
% B' h0 z8 I; P J" v# Q- // 传输完毕,关闭socket 7 w5 X6 k9 X# C/ E, _6 ]: ?* G
- fclose(fp);
: R/ |/ X2 q5 j V5 N% ?3 q - close(client_socket);
5 Q, J( o9 j+ k# L8 a _# Q" D$ M" c - return 0;
u" k4 |+ Z, q& N ~* Y& H - % I& [1 `5 F) h. N3 X
- } 4 P6 R6 k6 L; v, q- C( C" t
- ' W! _9 x- i2 V5 W' C
复制代码- /*server.c*/4 y) f, z. Y, \( G+ G
- #include<netinet/in.h>+ R8 B" u2 S/ R
- #include<sys/types.h>
7 e$ w( Y! P& h- V& a - #include<sys/socket.h>
* f4 T7 z" m& r" e. F - #include<stdio.h>
+ d: v% R$ v: q+ l0 o* Y9 x - #include<stdlib.h>$ q- m* s4 ? s r- z9 Q
- #include<string.h>
- U& k; \9 @ v' X4 d - / o, ~8 p2 d( v; f& x
- #define HELLO_WORLD_SERVER_PORT 6666 //端口号
* q3 M S. r' C D/ k6 x - #define LENGTH_OF_LISTEN_QUEUE 20
- _8 h O! A+ X3 R* r+ D) O- A - #define BUFFER_SIZE 1024
$ u% H4 l$ p2 p9 f; u0 i - #define FILE_NAME_MAX_SIZE 512; Y: |% H' u9 ]. B
- % l+ n }3 f! p& I. X9 [
- int main(int argc, char **argv); X- T2 O+ t, v" z! S, u0 r# R/ y
- {
2 e4 X6 u. L' p3 u* W - // set socket's address information9 A/ Q/ R4 I+ ]5 C! ~
- // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口
' r- }8 V \8 _. U+ P7 Z0 Q - struct sockaddr_in server_addr;
p# U& X. x. q$ G' N+ B - bzero(&server_addr, sizeof(server_addr));
. f. q w$ F+ ?) z - server_addr.sin_family = AF_INET;
7 Y# k$ N- _% _4 T/ Z - server_addr.sin_addr.s_addr = htons(INADDR_ANY);1 M4 v. j4 O8 v% Q3 P6 l
- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
, F4 ?2 i/ W3 b0 c% o3 H# U# k
: u9 I$ A/ p) H2 L- // create a stream socket
8 [! w* A" F# S4 V - // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口
4 F5 Q$ u6 [% l - int server_socket = socket(PF_INET, SOCK_STREAM, 0);
0 D, S3 P# Z: x - if (server_socket < 0)
$ R% |' L' K# _5 Z4 \, k - {
; ]$ p8 o0 p4 i l& j- {' `$ x/ V; W - printf("Create Socket Failed!\n");2 |# M& S4 X4 _1 n- f
- exit(1);* l, P" r9 L0 d& {
- }$ i( Z3 Y3 Y, K- h8 H* @0 Q
- ( s# q8 f. j: ?, E
- // 把socket和socket地址结构绑定
9 }8 y! Y( u; I# ] - if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))
, ]+ [3 F K' ?" C - {
2 ? P2 j: v' H; E. C - printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);
6 W8 N2 r! G) k- T3 B" E - exit(1);0 m0 R0 I7 G1 N. B0 I6 E9 L- W
- }7 h" g% U6 P3 `3 L/ n+ f5 H' y
2 V& j8 {8 @7 Z& |; Q% u) [! j! G- // server_socket用于监听* N# y; E2 R* l1 t0 Z
- if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE)). F5 u5 t+ g: i# p
- {+ M+ _8 k( m& X, I% {8 W
- printf("Server Listen Failed!\n");
% z$ @! r' g: D8 x8 B - exit(1);
4 p, ~! d% W# T* Y0 f - } G/ b4 k4 ]( K1 Q% G7 `
- : t1 y/ R9 j" h7 U
- // 服务器端一直运行用以持续为客户端提供服务- g/ e$ T% ], f* [3 G
- while(1): ~9 \; y9 v, A7 Y
- {! i/ V% e1 c( _' J# _* }* `
- // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept
! w! S9 g8 k8 r" y - // 接受此请求,同时将client端的地址和端口等信息写入client_addr中
' W; ~3 e0 E$ C$ _, ]: e% @ - struct sockaddr_in client_addr;- h* M& F. F. I
- socklen_t length = sizeof(client_addr);# t/ _* ]7 l; _9 W3 D. \
- ) K, y% [' L( f5 i- z
- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中: X2 K U8 k$ y; Z# Y9 Q: R7 }
- // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以
0 \% h' s+ ?1 k H( ^1 z+ v - // 用select()来实现超时检测- }+ g+ C1 g4 ^5 |; F- a. u' s
- // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信
* [, [% ^2 E1 x- h - // 这里的new_server_socket代表了这个通信通道
8 t' v' A7 N: J6 F- p( [ - int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);
6 \; k, _. P+ _3 p2 ] - if (new_server_socket < 0)
& u: v9 w+ }+ B$ H, G! Y - {
, J0 h: J! ?. x1 k. V - printf("Server Accept Failed!\n");2 a- m& }% B- y# D
- break;& t0 w; P' Z6 P
- }4 b" d3 ~( X9 z. ], f& w
( }. Z/ \" L, U& ^- char buffer[BUFFER_SIZE];0 R" Y$ w# g+ a7 i$ c7 i+ U
- bzero(buffer, sizeof(buffer));
3 X) S, b2 j' N: u) G- @& Y T" t, c - length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);: G; W. u7 s1 @
- if (length < 0). h) Y1 R# b% U h; m6 \
- {
+ E" p6 F; o: F - printf("Server Recieve Data Failed!\n");
4 n" z% l2 Z2 } - break;
; E' Y( h+ ^3 b0 x' R I$ b - }+ @; r8 c% i" b4 q# g
- H/ p3 C& B( H* F* w) Y& L& w- char file_name[FILE_NAME_MAX_SIZE + 1];' a) c3 f0 I) i. f
- bzero(file_name, sizeof(file_name));
) Z5 R+ U5 }- ~, b; u - strncpy(file_name, buffer,
% n0 Y- e' F$ K: E - strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));. _5 I9 U: b. @5 `' E
- & P3 }- d, u1 Q, B6 E W
- FILE *fp = fopen(file_name, "r");) _' [2 ]5 R* S% a/ t
- if (fp == NULL)
5 @4 C" a v8 t5 h# u0 E' ] - {- k, h8 V: f, |6 e
- printf("File:\t%s Not Found!\n", file_name);7 x2 M2 A$ s" e0 |
- }) Y6 \' Q- n2 |& j) `
- else- j- @. a0 N5 q- A5 v8 v
- {
: ]8 E* I; F3 t7 {! f1 a - bzero(buffer, BUFFER_SIZE);! a$ U# [2 ?' J: V
- int file_block_length = 0;
2 A0 D$ t+ c8 E0 L& V1 M - while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
' ?9 g8 s; M0 c5 o; E8 _5 p - {
# Q& f& R5 S& M4 u6 {8 s2 V - printf("file_block_length = %d\n", file_block_length);
. v9 M7 E' `0 h9 h6 J3 x
: S3 `: d7 u, C# U6 T* A- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端' Z# ^; f- L, T; f P8 a
- if (send(new_server_socket, buffer, file_block_length, 0) < 0)
* z' Q, c1 e: F& E8 H - {6 E9 T! q! V' i K9 ~8 V
- printf("Send File:\t%s Failed!\n", file_name);
$ R. R# n+ }; m* K8 p - break;8 w' J9 ]% t% _) L2 r
- }
# U5 B, c4 \. Y - # W5 J2 x) w) W M, ?: q. g
- bzero(buffer, sizeof(buffer));
% ]8 Y5 o. ^8 }2 l x - }
" x- _" l0 O; D$ H3 x$ O3 { - fclose(fp);
+ d I$ U$ W+ ]7 a8 X' r' Z( ]. z) H - printf("File:\t%s Transfer Finished!\n", file_name);
, `2 _- g/ l+ Y: x$ e# v - }
$ Y& \4 n- n" A" w \
3 U2 O5 | B' @$ t- close(new_server_socket);
$ \' z7 x$ i% B% Q7 d8 h - }1 G) E+ x/ @2 r2 N& t3 R. n
5 C) _) L, X; S- close(server_socket);! w! ]2 {2 m7 g/ r4 J0 F
- " t- ?6 j/ p, t! o# F; {
- return 0;
( }* s- C4 p( E - }
* `( e4 p/ I9 Y# R6 I - - u0 a' i4 p0 }/ M
复制代码
, d0 G. o% {% R4 a5 O
% F- O& V. z; ?$ t
4 t* @9 [0 e# Z' ^, V
. [. i0 d0 q* B0 B3 s |
|