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

楼主 |
发表于 2020-5-9 01:48:09
|
只看该作者
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段.
; `) Z5 r. h* o: j2 e2 S7 i# C- /*client.c*/# \$ _, @+ u0 g% m) `- V6 q
- #include<netinet/in.h> // for sockaddr_in
1 \" i" L0 {3 N - #include<sys/types.h> // for socket ' L5 X5 }3 O0 n8 O3 R3 Z
- #include<sys/socket.h> // for socket
- r1 u q4 E" S# r9 ` - #include<stdio.h> // for printf ) E% t: g+ b7 m t0 ~' U
- #include<stdlib.h> // for exit
' L4 U, s* p0 c( A5 ]1 u - #include<string.h> // for bzero ; z( c6 q2 Z/ `2 O
- 2 _ ]' g& Q% r& [
- #define HELLO_WORLD_SERVER_PORT 6666 ; |! ^( c% B0 J! m' a5 j
- #define BUFFER_SIZE 1024 5 b# c% p! k4 ]+ ?
- #define FILE_NAME_MAX_SIZE 512 : ?9 ?5 t& r* m9 ?* T$ `6 X' M1 g
3 M& c0 L& S( l+ U/ }/ P# ?- int main(int argc, char **argv)
3 N2 i! a a' r( ~2 i - { ; l. R* {3 P4 o7 f
- if (argc != 2)
7 Q. c" x* |2 ~1 @9 ]# T9 b - {
( \4 ?+ j0 ?; ]: d4 L2 E" d' |8 N% ` - printf("Usage: ./%s ServerIPAddress\n", argv[0]);
' R, g. E3 z- C6 ?4 ^0 P& b' ]$ U - exit(1); - k3 s7 ^ b8 ?+ A6 B* g
- } , Z) k1 l3 a* H% V' n
- 1 |1 H" f: c) l
- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口 2 o; E) `* s% P8 S @5 I: l1 U
- struct sockaddr_in client_addr; . \0 {8 w+ a8 n1 o% e
- bzero(&client_addr, sizeof(client_addr)); 5 z: z# a9 X7 s: [ m5 q
- client_addr.sin_family = AF_INET; // internet协议族
; t+ M( m" u# m' ^8 _. ]; G8 J& Z - client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址 - K E1 ~0 H3 Q g! b: w
- client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口
* ~( R) {9 w4 z, r/ |1 `' U - 3 ~9 U/ S& J* E" a
- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket
; R# Y5 y9 J" Z( u7 S - int client_socket = socket(AF_INET, SOCK_STREAM, 0); * a# p8 f9 D; Y3 N& s# T4 G6 Z
- if (client_socket < 0)
4 G, o# I% l% F8 b* i" m3 C - {
9 W2 B$ r6 T2 B: ?1 m - printf("Create Socket Failed!\n"); ) h' @6 v; \) j' V# k8 Q
- exit(1);
9 e( G* s U9 f1 m x - }
: i$ ]5 h( ?0 T- _ - 3 \% m! ^ {3 D! n* {2 z4 e f
- // 把客户端的socket和客户端的socket地址结构绑定 / z8 m; B$ \8 l G
- if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr)))
6 K5 `* F+ Q0 R7 Y% C& K - { ( w; E% I7 u1 T: Q
- printf("Client Bind Port Failed!\n"); 5 X# B. ~ |% w& ?& Q Z; o. ?
- exit(1); * J% s8 j- ~8 [* u/ y @$ R
- }
& `/ x% l/ p: o2 W, S - " Y; [% c8 J, v4 {. B+ x
- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口
" |! V9 i4 a8 v! E* I( j& e - struct sockaddr_in server_addr;
3 M2 }& `+ R) @- s8 W; W. F4 S% | - bzero(&server_addr, sizeof(server_addr)); # \: v( x {5 [1 Q
- server_addr.sin_family = AF_INET; 8 l. Y' k& Z1 L6 {
- 2 c2 R5 k# d- W, Q. ~6 ^' n
- // 服务器的IP地址来自程序的参数 ! \$ \7 c! @$ j
- if (inet_aton(argv[1], &server_addr.sin_addr) == 0)
- M, `* F$ r y - {
; ~) j3 ]: R P4 O0 K9 w5 { - printf("Server IP Address Error!\n"); ) P j. ?* n# P; \' n
- exit(1);
# C: s* ^% ?. ?) W7 C - }
9 e9 _. h7 _* v; C, V" G
+ z4 l; y0 o" q8 u: q* F- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
$ h' X0 A. }3 ?1 X - socklen_t server_addr_length = sizeof(server_addr);
% E0 O. h, J* N - # D0 b8 e2 B; _" _5 i5 N( h) W
- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接
7 r" t ?0 c3 A4 m* E - if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0)
$ v9 v9 ~7 |) c! D5 L2 P/ Y& P - {
* G9 r( [7 M! R+ V - printf("Can Not Connect To %s!\n", argv[1]);
% a- Z7 o8 q* r% n6 W- g U - exit(1);
& \1 @7 H; B4 T& E' X( k - }
$ V Z& Q( b$ x. K) H0 p; ~) _- I: l
% b& P% o' b; n) T# \- char file_name[FILE_NAME_MAX_SIZE + 1];
" ^6 q- Z u+ @8 U - bzero(file_name, sizeof(file_name));
- Q1 P6 W4 O; m; Z! m( T - printf("Please Input File Name On Server.\t"); 3 M% F, w* i( L. R
- scanf("%s", file_name); . X8 J1 ]) ~' o u$ u: U" P* G
- . S4 n3 l8 E, U5 |, G8 A+ i% h$ V
- char buffer[BUFFER_SIZE];
% i3 j c; e9 T) o1 V) h; T' e - bzero(buffer, sizeof(buffer));
, ]4 t2 C( o/ }; m; c, S - strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name)); : Q9 u$ l# A7 Y: ]- Z4 r9 F
- // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字 # o; W$ s9 r+ |1 p d& {
- send(client_socket, buffer, BUFFER_SIZE, 0);
. \' {5 B# Q1 G# p - 6 p2 f( Y$ g8 o( T& @
- FILE *fp = fopen(file_name, "w"); / k+ ]2 S1 g& }; C% W
- if (fp == NULL)
3 H2 j- B6 H! G8 a, Y+ |: G - {
6 }$ `/ y7 I6 n - printf("File:\t%s Can Not Open To Write!\n", file_name);
. y3 w9 K+ o! B* Z. `1 F8 _+ G& D - exit(1);
" b' X0 ~/ z( T0 R+ r - }
# O4 O& X" @4 V' ~6 \6 o. ~$ C1 A - + W1 v+ ]; u) ~9 |& N$ l
- // 从服务器端接收数据到buffer中 0 R, r) M& ], W! X
- bzero(buffer, sizeof(buffer)); ! c+ V3 ~- T& y4 |% J6 @( q, R
- int length = 0;
( F- Q8 a l7 B - while(length = recv(client_socket, buffer, BUFFER_SIZE, 0))
- Z4 i0 J8 `. L* z# f - { ! g4 J" L& i9 n% E# j' z! h; z5 g
- if (length < 0)
: m& A# T* a5 e+ E, ] - { # s! z- S' _+ U
- printf("Recieve Data From Server %s Failed!\n", argv[1]);
3 e0 s" n: j0 j% v: c$ \" p% q" Q - break;
8 X( r. j0 H9 Q( \& x8 g - } B' n% K6 g, z5 }& n; E6 z9 D
/ _' A5 i2 B3 k8 U- int write_length = fwrite(buffer, sizeof(char), length, fp); ) P9 s7 `& _ L
- if (write_length < length)
# r8 `8 E/ A4 \& q. O/ N8 _2 e4 N - {
6 d3 p, o$ o& M7 w0 i - printf("File:\t%s Write Failed!\n", file_name); 7 Y$ `' ?; ~- [, m1 _
- break; . V h" u% T* K2 l$ J% o
- } & B4 Z; t9 y+ \* v
- bzero(buffer, BUFFER_SIZE); % X1 E2 A5 J, ^. `( I
- } % t+ r; F3 H& g& ^! u& ?& R
- 6 n+ X+ u9 ~$ G, L( q2 E
- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]); 8 W' u* O8 `+ _; p4 w
- , V* v2 F/ _4 K
- // 传输完毕,关闭socket
7 P5 {& n/ }7 c- S - fclose(fp); 7 n, b" j) p; M
- close(client_socket); 9 e. g- S3 i3 }9 L0 J" q0 |2 x
- return 0; ) `7 G' Y6 J9 V6 I: l% G
. y1 x! F. @/ p4 I- }
5 ^" c/ v. @/ k: t- M9 A
2 L- |1 w: [, X9 l. M# W y
复制代码- /*server.c*/) y' \2 G! C) x1 f
- #include<netinet/in.h>/ p( B/ `( u' j) m
- #include<sys/types.h>
+ P' T% _& f/ Z6 o, o" Q' X3 A - #include<sys/socket.h>, k B3 T6 E/ {
- #include<stdio.h>
- `) P6 z: z% W6 T7 `" p - #include<stdlib.h>/ f- z7 t; X0 y) X6 ^8 [3 B
- #include<string.h>8 u2 r7 l- ^6 w! x- o i2 [
- 9 ^* B# {' w6 z1 s
- #define HELLO_WORLD_SERVER_PORT 6666 //端口号
$ |- ^$ h7 C9 V h4 I& v' l, \6 j - #define LENGTH_OF_LISTEN_QUEUE 20
* C# }/ T" b2 y8 C+ X7 q - #define BUFFER_SIZE 1024
( s( K' ~( n. r9 M8 D - #define FILE_NAME_MAX_SIZE 5126 k5 K1 r, K* X u! H
- $ q% v# w" c/ O1 }' J
- int main(int argc, char **argv)* V' i: r* H$ Y i
- {8 H9 p1 L) M) _; Q) T, F( ~
- // set socket's address information
9 J0 ]" v4 Z$ W; r( g - // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口$ r7 m5 c+ c1 n9 m
- struct sockaddr_in server_addr;
0 h( p% N* @( f; D - bzero(&server_addr, sizeof(server_addr));" a0 k0 c3 E7 \% G8 b* p
- server_addr.sin_family = AF_INET;) U7 y, L) E! z, G
- server_addr.sin_addr.s_addr = htons(INADDR_ANY);
: c9 `, @, j) t# | - server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
* n+ h9 L% Y! h4 u - - q7 [! ^$ d3 N1 M, v
- // create a stream socket
9 ^& i9 E, X; V- G3 g' o - // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口
' n* l- g: j% f; |" W `, }# o. E3 q - int server_socket = socket(PF_INET, SOCK_STREAM, 0);
& w8 h' [5 E5 l( p" D9 w- ]/ C - if (server_socket < 0)* V/ |/ {% Z# `3 {
- {: B! b4 I( Z: S4 m' {
- printf("Create Socket Failed!\n");2 ^; e- Q; M; p% L& a& F7 u: ?
- exit(1);8 M/ u+ T2 J" w# I0 s+ c/ [
- }
# I% K4 N" j2 e" x) B; P
8 q7 f/ h' j% S, O" K- // 把socket和socket地址结构绑定( ^" w% u! I6 W7 Q$ {/ w
- if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))
! a1 a5 I) S0 g2 X6 I+ k. J- k: E - {3 M/ O) z& W @; `% y
- printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);
3 O/ w. x: C; |5 c5 ~" ?' ~ - exit(1);
) r5 _+ Y) `8 @1 C& o - }
9 p- Y$ i* |/ ?) X6 U5 T/ G, ~ - 5 x7 j$ J' {6 K6 p, N
- // server_socket用于监听
" M0 R! U8 |" E5 V' Y' S - if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))9 c& ^0 V( t/ Y8 _
- {
- a* H3 z; F* v4 y) n) l - printf("Server Listen Failed!\n");
& n' |+ x, U2 B0 \# h7 R% K - exit(1);8 d) S- b5 P' W& {8 c
- }% {( b" n( O# {7 C% l7 ~
- , a- L9 b8 `: J# W+ W
- // 服务器端一直运行用以持续为客户端提供服务$ C' n" l0 J# U2 |
- while(1)
5 T8 t8 L3 M W- ` - {
. N9 P8 G: {7 M0 P - // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept8 B0 I+ Y! n+ j* C# `/ f
- // 接受此请求,同时将client端的地址和端口等信息写入client_addr中
* Z7 ]) u2 {8 H; \2 | - struct sockaddr_in client_addr;' ?) M2 v% i6 Y; a
- socklen_t length = sizeof(client_addr);
6 _( N6 K' Y1 L- M2 {4 I
% Y) y! l& F# Y- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中5 F# K0 e/ x# Z- i- g* Q8 n
- // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以
+ U- l2 a2 N, `. ` - // 用select()来实现超时检测5 D7 Q* G9 e. W
- // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信& `' P' L/ @, \+ t
- // 这里的new_server_socket代表了这个通信通道
9 d. Z( _9 E+ ^) L) E# g: R - int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);
W; f( V: U. V3 N* ?3 e+ G$ ~% i: I! i9 x$ S - if (new_server_socket < 0)
! M6 I5 }) P/ y/ U+ f: D9 k - {
. W* J: H- U( d$ W - printf("Server Accept Failed!\n");, ]5 e6 ` f3 s1 u
- break;
5 x+ ^3 b& [3 c - }
& i; _5 @5 J. m! k o+ \& A2 @
$ L/ K& w" Z/ L K- char buffer[BUFFER_SIZE];8 ~4 a3 u+ j7 a1 a8 `! o; q
- bzero(buffer, sizeof(buffer));$ }) Z h6 G$ J1 W, `
- length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);( M: E9 _( D d( r8 j
- if (length < 0)
* m& v7 ~7 x1 V2 X - {* m, }/ Y+ a9 Q; o, u( G
- printf("Server Recieve Data Failed!\n");
+ H6 G( h! k$ k, x! {( B$ d. t3 j - break;
! C% [" A$ z8 d) @, W - }
7 n4 e2 C3 Z/ v" l - - `" g' }" w- ?) s
- char file_name[FILE_NAME_MAX_SIZE + 1];# Z( H6 O3 J# w) o* |
- bzero(file_name, sizeof(file_name));
, }3 }3 p$ Q+ G" p - strncpy(file_name, buffer,
# q; }2 A G$ b2 b2 { - strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));
- m. r8 |7 ?% G) M o0 f$ S9 | - . ?# g3 Q% Z) S1 t& j5 E
- FILE *fp = fopen(file_name, "r");
. a6 A6 G9 b5 Z, Z - if (fp == NULL)0 h Q7 d4 k, M- q" g% g
- {
8 W2 D* M0 P, v+ _( e - printf("File:\t%s Not Found!\n", file_name);' Q4 }# g* r8 ?) J
- }
* K# d! u, ?1 r - else
- u. Z: \; T% [, P/ J' V% r. Y - {3 r4 ^& t6 d& G) Q" L* k! W
- bzero(buffer, BUFFER_SIZE);
9 J! D, r$ v) d& ^ - int file_block_length = 0;3 b1 v. T2 W. Q7 U3 ?$ u7 l9 }
- while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)# L# m9 e# P r! j
- {1 i" ~; t3 l' P
- printf("file_block_length = %d\n", file_block_length);
- |; y- J* ]3 z' C
- U, Z* G0 e$ }1 ~- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端
$ N3 Y$ n t$ Z) A7 _6 N - if (send(new_server_socket, buffer, file_block_length, 0) < 0)7 U+ ]; W- N4 w, }
- {' a2 n$ k7 B* T Q/ j! T
- printf("Send File:\t%s Failed!\n", file_name);
6 {! p2 }; N5 ? ]. T. z - break;
/ B; `9 P9 _/ o2 A - }
: g/ S: i3 l+ m3 B) R6 a. _ - . A1 c9 q7 j5 w0 X+ V
- bzero(buffer, sizeof(buffer));, E2 Y9 V* t5 m% o. E
- }
; ]# G# K4 w3 _5 G# o: c. ?) E - fclose(fp);8 ]& R% f1 Z8 U) h
- printf("File:\t%s Transfer Finished!\n", file_name);
2 @1 V1 |6 u F) p* y - }
! t. n H8 g4 L: y) n
/ [+ b' l4 ~/ I+ E$ a& f& r: B- close(new_server_socket);0 U& z- y/ k0 `
- }
2 P& c8 [8 r) |4 G; k
; O/ J: ~% q9 ?: n' v- close(server_socket);% \1 F% u) g! R' {
& N, z) D; ~( c& q" v9 B$ L- return 0;( J1 i4 P: y3 z1 L9 k5 v
- }+ S W P6 i+ m% Q9 S" Y2 X
- % Y- p& v1 g- J9 d1 d& E X
复制代码
$ _7 P1 e4 P# M3 f/ g" M( s# T% r8 k6 h' i5 m
) W3 c u$ k% k6 O
" ]" Z! {& m/ Z+ d( v' B. v6 @ |
|