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

楼主 |
发表于 2020-5-9 01:48:09
|
只看该作者
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段.
& C% Q: _9 M2 x- /*client.c*/
5 v2 Z+ W# L+ `- Y) G/ r - #include<netinet/in.h> // for sockaddr_in
: p, P: a3 E7 F: Y - #include<sys/types.h> // for socket ' M& R& `5 ^! |$ d9 D- g
- #include<sys/socket.h> // for socket 2 V! p* u. G0 x* A R
- #include<stdio.h> // for printf
X* |! k+ [4 J% \& O - #include<stdlib.h> // for exit
& s; C- A9 I* r O. V4 w& F - #include<string.h> // for bzero " w; V2 P+ s4 X4 t* d
( l* P( r4 e/ H- #define HELLO_WORLD_SERVER_PORT 6666 & y3 L: H5 \+ Q- ?" `+ c
- #define BUFFER_SIZE 1024 7 J7 ~+ F/ i" `% a" n( f. ^2 C
- #define FILE_NAME_MAX_SIZE 512
4 F# b0 a6 i9 K, u - + y8 z \: G0 K3 I
- int main(int argc, char **argv)
; H# @ h9 T2 E0 p - {
. S o b& h0 w3 V# q ~9 q - if (argc != 2)
8 Q' J3 L+ Z8 s: d" c( G8 x3 J - { $ y* X1 ~$ e9 t5 x/ I
- printf("Usage: ./%s ServerIPAddress\n", argv[0]);
) C2 B1 V. D/ v; z" Y$ U9 Z+ x2 B - exit(1);
' ]) U2 K+ }) T& B Y - } ) D( N% W Q, q7 E6 u% k+ J+ U
- ' q( g" I- D2 M4 t
- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口 / I) o, e0 A/ _1 ^
- struct sockaddr_in client_addr;
/ u' L( q% h3 r; Y2 m1 b7 j - bzero(&client_addr, sizeof(client_addr));
+ b1 J* |9 Y8 B; b% j% q @' N - client_addr.sin_family = AF_INET; // internet协议族 9 x% V2 r; z7 Z& ^
- client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址 ' S: H0 G" G! v, D5 a
- client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口
8 v/ L+ ^0 q& z- V# ^/ n
: B2 w, J5 W0 D, ^1 T7 c+ P- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket * x9 p/ h5 E# l- }
- int client_socket = socket(AF_INET, SOCK_STREAM, 0);
% R6 n$ U8 I" Y- \7 y - if (client_socket < 0) & G- _2 Y! U6 |) C3 i
- {
2 G# i# G" l* l - printf("Create Socket Failed!\n"); 2 M/ c" X! W; }8 `( V: r- c
- exit(1);
* j5 H6 T8 P5 _ - }
- B1 v8 M/ x% O
0 w' O. v4 Q `. P6 R- // 把客户端的socket和客户端的socket地址结构绑定
& Q6 d: |6 B$ P4 G) y - if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr)))
/ m% B' x; ^1 k$ Q" E1 U7 e - {
( m% h8 k0 C3 K" q2 [; B8 C3 O$ P - printf("Client Bind Port Failed!\n");
; K2 q' Q" ^' W8 y$ w- B- q8 q. i - exit(1); $ I. h9 v& ]8 {5 x7 z: r/ I% `' O' t
- }
$ Y; X7 w5 g" m+ ?0 s
. i' v3 M/ M, V2 i5 @- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口 7 @) Z, z( E' ?+ @% K
- struct sockaddr_in server_addr; 7 ]& v o. P7 W Q
- bzero(&server_addr, sizeof(server_addr));
. K, u( S; ^& p+ r) P, G0 ~" D - server_addr.sin_family = AF_INET; % E: ~, F1 ^- B8 v! ~) [
I; n( R3 v4 ?5 M- // 服务器的IP地址来自程序的参数 ) _7 I" b7 T0 {4 W r- N$ |
- if (inet_aton(argv[1], &server_addr.sin_addr) == 0)
y" p* w3 Z% L' U6 m }- J$ T6 o - { 0 L, v; s2 P1 ]
- printf("Server IP Address Error!\n");
% |5 S+ f9 U0 z X: N3 r( z - exit(1); ( K J) X7 s/ r3 h) k) D+ G
- }
5 e/ o+ v3 U& ^: t5 j - , F! ^' @* ]: d/ B
- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT); 8 k5 F; \8 i( L ?+ b5 h
- socklen_t server_addr_length = sizeof(server_addr);
* ~# k m) B$ ~5 B8 O' s5 ~# y
5 r- o$ G" d" @" B; y6 ^, S2 d- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接
( t, b/ i, ^) I j) d; v9 V& `! s9 A - if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0)
' Z, F. r+ D0 A) F4 a. w - { ( u/ j5 s3 e- j0 R
- printf("Can Not Connect To %s!\n", argv[1]); $ @6 b- c% m- Y: O
- exit(1);
: g. m6 u3 p( B! l - }
( k5 V' |- g5 Z1 [0 _1 i
- j: v& }0 B+ q$ K& S- char file_name[FILE_NAME_MAX_SIZE + 1]; 2 c: B) R9 W: A+ ]" G
- bzero(file_name, sizeof(file_name));
- b9 w R6 K, X5 O - printf("Please Input File Name On Server.\t");
; b4 l7 H' q; w9 w0 I4 I - scanf("%s", file_name); 3 g* ~3 Q( h. f$ c' V0 |* o
- 1 r$ @) Y0 e1 g* ~- S2 n
- char buffer[BUFFER_SIZE]; ' v) V( @: Y) r9 R. o+ {
- bzero(buffer, sizeof(buffer)); $ S; K3 A% {+ Z1 u; {2 a
- strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name));
' s+ N4 i$ z' s) p - // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字
5 e5 ^+ g+ C7 Z8 Y3 V+ } - send(client_socket, buffer, BUFFER_SIZE, 0); ; \3 k" y) U1 ]. e% w
- ' S" L2 D/ Z. k$ T, E6 f
- FILE *fp = fopen(file_name, "w"); ; p1 H% v! ~0 B* `7 o! Z, d
- if (fp == NULL) , B" w" X' ?% p
- {
& P+ J$ T2 j$ G& T. L' F - printf("File:\t%s Can Not Open To Write!\n", file_name); * H4 s- t# S$ I' O1 J
- exit(1); + d! K9 [5 O5 n0 \& O
- }
( N: z( l1 W: k
- s" a/ K" r: f0 k3 |, B8 n0 }4 J- t- // 从服务器端接收数据到buffer中
$ t9 t9 o1 d, Q - bzero(buffer, sizeof(buffer)); 2 O$ I K3 P* F; Q
- int length = 0; $ [: F* l" Q. i9 b
- while(length = recv(client_socket, buffer, BUFFER_SIZE, 0))
. F% g7 p% C) |$ B1 Q% e - {
# |; Q* A+ U4 i( _ - if (length < 0) % ?' a6 l* @. E4 D
- {
$ Z6 }: a& d t/ K6 n - printf("Recieve Data From Server %s Failed!\n", argv[1]);
: _4 B, ^, Q I5 ` - break; % m6 m! D0 O$ U1 `
- } % w2 z* _+ m, x/ }, ^
- ! A. D7 y9 t4 J$ ^ g. r6 i
- int write_length = fwrite(buffer, sizeof(char), length, fp);
}" h3 B& Z, N. h( ?; i6 i& v - if (write_length < length)
! E" q) O( ]( ]. v% H - { ( W" d1 w' [3 o4 k1 H. e" W
- printf("File:\t%s Write Failed!\n", file_name); ' F/ S- `& y/ H$ V, Z* v, Q
- break;
$ ~3 r& z2 k+ B2 [: r. Z9 B - } - o- K' N; x9 L( P
- bzero(buffer, BUFFER_SIZE);
4 I! r: i& a8 z! P% f: S - } 7 g, p+ B. M! N4 V4 R9 @+ a
( t" w$ l4 i% J( @( g% A- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]);
# M4 _# D9 E3 L* i
' H3 T1 |* n1 w; T2 D3 C- // 传输完毕,关闭socket
& u: Z$ J* s+ f3 [, q - fclose(fp); : V8 |5 B8 a. h5 ?
- close(client_socket);
, c7 n" x. N. G# }7 `; a+ M - return 0;
9 c8 k! U8 d; y" u; C; Y1 X - * N9 P1 F% s% x/ s! o0 p2 ]
- } ! r0 `) b l0 i1 q8 T
- ( d/ q$ u* t& b3 x9 X
复制代码- /*server.c*/0 f( d( x9 N/ _9 y8 [
- #include<netinet/in.h>
7 X9 V3 }$ q4 r) r* b) R0 t& Y$ F6 j - #include<sys/types.h> d6 M# y3 |+ Q0 d# g: F% |8 f
- #include<sys/socket.h>
/ a1 e* s& R- ? - #include<stdio.h>
9 v/ a8 P0 f$ H9 X# l, R3 w# H' D - #include<stdlib.h>
8 t5 F- F4 w2 |% \- ?4 I$ ^ - #include<string.h>
, }1 A9 a5 q! t5 R) g# f - . D% [; v/ ~; }8 _: S. \0 W, j
- #define HELLO_WORLD_SERVER_PORT 6666 //端口号1 W) B! W; O, w
- #define LENGTH_OF_LISTEN_QUEUE 20
5 E8 V E: v5 z& y3 W" K - #define BUFFER_SIZE 1024# U, y1 u. x" P' d) g; W( u
- #define FILE_NAME_MAX_SIZE 512
. f' M) e+ R Q4 R+ Y
) P, V' {: D- n* z, _1 X) m1 P- int main(int argc, char **argv)7 @, m5 b, r* f$ G h# T
- {2 C* t+ F2 l, M; Q9 u7 u
- // set socket's address information
' m' i+ c! A+ h - // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口
! C0 N+ D9 s- c0 r8 s) G - struct sockaddr_in server_addr;' K$ H# k3 j7 G% ? n
- bzero(&server_addr, sizeof(server_addr));* \) O" d Q2 [1 r
- server_addr.sin_family = AF_INET;; P) R* S/ b" n; H- c. O. x( \
- server_addr.sin_addr.s_addr = htons(INADDR_ANY);1 `- _# v4 z8 U5 Q8 i7 \$ F1 e
- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);# S0 V+ q" r! b& D: {6 C( y: k8 ~
- : X& s3 v! z) m) I4 }5 O" v
- // create a stream socket
3 @ q @7 F1 [6 d5 ? - // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口5 X( V4 F, b, U4 F4 Y$ l) {
- int server_socket = socket(PF_INET, SOCK_STREAM, 0);' Q8 P" L3 V4 n, H, _
- if (server_socket < 0)
: }! O/ B4 I5 V - {
$ W: Q1 s. R6 }! r! g3 A - printf("Create Socket Failed!\n");) z3 s, I& N( R# k8 E4 l
- exit(1);" D ?- k! k( n; T1 f% u
- }
9 ]/ U `; t8 T- ^6 @* f$ z* C* d% H- y- e - ; N$ v$ P+ @% o0 G% ~" E
- // 把socket和socket地址结构绑定
9 i+ d, w% d0 W - if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))! Z# D+ h+ X/ I) r. P' b2 f2 l
- {5 w( i$ M3 N: `* S1 _$ k
- printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);
9 J( k' Y% s$ w' V+ S0 v6 s - exit(1);
6 `; L& c# \. u" J - }
4 \ `' b4 o# o& @8 e) c
( l( p8 l6 |5 {8 O8 v' ~- // server_socket用于监听) |8 l4 K8 t6 k7 y
- if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))
( t6 O2 W5 m* q1 h( l* e - {
: K- b/ f( z$ q- ~* r - printf("Server Listen Failed!\n");
* O3 m; t3 g' _# z$ s' A9 n" S - exit(1);
% X; I/ t9 ]# I X' k - }
+ H a$ `( P" S0 s( R3 S
8 G4 m, ~0 D$ p" ?- // 服务器端一直运行用以持续为客户端提供服务
1 ~0 N* O/ F3 J/ D& }5 ?! I - while(1)
( j* R! N3 ]0 x0 P+ n: s6 \# M. j - {9 Q: o& p' v* `5 f1 Q
- // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept# v; w h( H4 Q; F b4 U. ~: ]1 o
- // 接受此请求,同时将client端的地址和端口等信息写入client_addr中
7 U2 Y. i9 `) w: [ |0 M) @ - struct sockaddr_in client_addr;
3 V1 o# G0 j) T3 W1 F) N- x - socklen_t length = sizeof(client_addr);
; w9 C6 `* w) x+ ^* q
: N) c5 n, Y+ e& M- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中
# V: u0 f1 O2 r' X- L - // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以) }/ I3 A. Y8 @1 G+ A5 F
- // 用select()来实现超时检测
6 v3 I9 D5 ` U' o4 } - // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信
V+ E$ Q0 Q- w2 u( y' X2 m - // 这里的new_server_socket代表了这个通信通道
9 q0 X1 l$ I5 D" n' {3 h! j" P: d0 _ - int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);
7 C6 K0 H+ E# Y& g& |# G0 m - if (new_server_socket < 0)4 Y* q( p. X% J- ^7 u
- {. N" l; A2 ^2 o; G+ p
- printf("Server Accept Failed!\n");
6 I. k4 G' H7 z$ ~0 u" l7 I7 L - break;: i- u9 U6 B# M2 Z/ W7 Z" m
- }% Z1 s( r, q4 s7 t, \/ |* S
- 2 Y. l" T9 e I4 Q) K# t6 E" [* K
- char buffer[BUFFER_SIZE];( n' M! p3 h" Y' S9 R K5 v
- bzero(buffer, sizeof(buffer));) ]9 n0 P& d+ G+ N" {& L
- length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);# W9 W' j' q& F+ W
- if (length < 0)
& M" I! i: [+ n - {2 g* B/ ?3 W$ w5 ?7 e E- U
- printf("Server Recieve Data Failed!\n");( k7 {: Q% ~( f5 y9 s
- break;3 Z, _, M1 O" B0 i
- }
; v; P8 O6 n: q0 H - * _# o5 k5 S# X1 ?, i
- char file_name[FILE_NAME_MAX_SIZE + 1];
1 a2 S- Q4 X) p: u - bzero(file_name, sizeof(file_name));
" R$ A; q n( F$ C K - strncpy(file_name, buffer,+ H- E- t7 x$ q! P3 i2 h/ Q
- strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));
* f& k' N! V0 r+ w( b - 9 {8 S8 l8 s1 ?+ `0 \* K
- FILE *fp = fopen(file_name, "r");0 T. w7 g. \( N6 {: i
- if (fp == NULL)
- Q; K0 b1 [* _% Q. q4 o' Q5 V( v4 L - {
' D; i4 ]2 i% T8 k# z( n* F - printf("File:\t%s Not Found!\n", file_name);7 Q- V" Y S0 l: b& j5 X/ `5 f1 t
- }
+ b7 D u/ l9 A5 Q' U% R0 h( k - else
" W0 |2 R% u7 r' ? - {
2 B9 [' X8 Q7 J$ [4 u9 m - bzero(buffer, BUFFER_SIZE);1 w2 l$ O2 [1 K6 t( h( V
- int file_block_length = 0;
0 C, D- L9 s k) v - while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)) ~# W. o3 c! G' `! b. c
- {
& t+ r; M/ |2 T2 o4 `- r A$ d - printf("file_block_length = %d\n", file_block_length);
8 l4 D; V6 P& Z - 1 ]& }* F( e3 | f+ c" S" |$ G
- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端
c5 M' o' B* o3 c8 ?+ x/ N' M - if (send(new_server_socket, buffer, file_block_length, 0) < 0)
6 h# K( A3 L m6 d0 A - {5 D2 X% |4 O( }. J' |
- printf("Send File:\t%s Failed!\n", file_name);
# Q( U( `- v5 ?1 ]% C T - break;
: E$ M- @: h$ l - }* d* f* ~! _- b! `! y5 x' c
- 7 ?; X& u$ o& X. g* G
- bzero(buffer, sizeof(buffer));
+ B; F. [$ H$ l5 S3 Z' h - }
" {0 ?# Z; ^0 E7 S5 h! p# R9 \: ? - fclose(fp);8 A; J, R! X$ C- l ?6 j- U
- printf("File:\t%s Transfer Finished!\n", file_name);
- x$ P5 f: q5 z% |% C; i8 K4 [& q - }
) k2 a2 E, f* d$ P- _ - & B0 n5 {2 F5 o4 e: t
- close(new_server_socket);! t/ z$ k' C2 Y; i2 l4 b( }
- }5 D- d. ]( A {1 e* p9 F
- 4 ]. r8 q3 _% ], @ K# i* x, r/ C
- close(server_socket);: v r# ]* L2 g. R, l5 C& J' U
1 S0 a5 `: N7 V5 Z- return 0;
( D& B& s$ Y# x+ a/ p" S. ~# A - }
8 Z6 o( ^9 c- N - 8 u; B- F9 T/ G8 E/ f
复制代码
3 j, T: E, ~2 M3 x9 B
4 x" X8 C# y. R9 g+ _4 W. P+ q9 A C! d: z1 J. b4 f8 c
* Y* b3 e0 u( K1 i) P |
|