管理员
论坛积分
分
威望 点
贡献值 个
金币 枚
|
沙发
楼主 |
发表于 2020-5-9 01:48:09
|
只看该作者
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段.
0 g* h2 F9 T* u v' l% c- /*client.c*/1 `2 D3 y- d e/ H' J. B% v
- #include<netinet/in.h> // for sockaddr_in ; A3 G) Y! R* |- f( j
- #include<sys/types.h> // for socket
8 a' U" J6 d- r' |5 x X' C - #include<sys/socket.h> // for socket
# A. z+ K+ N! H- @9 U - #include<stdio.h> // for printf
7 f/ h! J/ u8 R: m8 P5 r1 Z - #include<stdlib.h> // for exit
3 a- C2 a# a& J0 \2 a - #include<string.h> // for bzero
! r- I* Y3 J' y/ X3 H8 q. [ - ' v/ F6 }- u; b3 M- d# a
- #define HELLO_WORLD_SERVER_PORT 6666
5 a* f3 U- S3 Z; z4 {1 B5 d - #define BUFFER_SIZE 1024 " y) _9 q' y2 G9 @( P/ a
- #define FILE_NAME_MAX_SIZE 512
" N: X6 ]' @* X$ U7 a
2 t0 m* v3 Q: J$ h- int main(int argc, char **argv)
9 z& J$ z# N2 e' Z1 E. u - {
( O. l" S( X: F5 R- s - if (argc != 2)
! I% x0 b0 q" X7 A5 {* Y9 Q7 T - {
# X1 j8 Y, k; d) Z$ l3 L - printf("Usage: ./%s ServerIPAddress\n", argv[0]);
- d/ k. r; T. d! Y - exit(1); g8 O# c8 t9 ]2 n
- } + i+ \. N3 D. X b
$ W. o# p$ y/ q4 J- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口
* _8 k6 E/ a2 Z1 W- ?; V x - struct sockaddr_in client_addr; 8 q" E" c+ a9 H" }! Z
- bzero(&client_addr, sizeof(client_addr)); % `9 P2 b) L- l' U7 b T3 N" k
- client_addr.sin_family = AF_INET; // internet协议族 ! D; i3 o/ p, \$ i' e( y
- client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址
8 ]* J3 X- S. _- U1 Q - client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口
0 w! _7 ]+ w( G1 X9 a/ m4 w6 m
4 H! a! R4 f2 x: \! k- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket " A4 E G" [) b/ Z6 `! v0 ]# u
- int client_socket = socket(AF_INET, SOCK_STREAM, 0); ' C8 n* \& K4 G2 k5 G
- if (client_socket < 0) ' ^- g7 B7 q- N' c3 k. F1 }. A6 E9 ~
- {
1 E2 V9 Y) f3 e5 @ - printf("Create Socket Failed!\n"); * g2 x+ ^0 T6 e
- exit(1); # k, v2 J9 N G1 }: i( L6 [6 d
- } ( v6 N- r" i+ M) _
0 y2 Z$ W9 `+ r; V' O8 g- // 把客户端的socket和客户端的socket地址结构绑定 - x& B- z& d* y: M w8 t. h
- if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr))) 7 C$ O0 O9 c* P% u7 [2 n4 n
- { 6 u+ m( P! [0 a0 Y8 @
- printf("Client Bind Port Failed!\n");
2 q0 {# A. }) ~ - exit(1); ( s. {, ?0 ?5 e
- }
# P+ \$ `7 q4 l" Z- \# R) l" x, Y) \
. u2 B9 n6 T2 W6 r p/ z$ o9 d+ ?( }) ]- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口
+ ?* p9 g" a/ W3 L+ W+ u - struct sockaddr_in server_addr;
) C4 _5 p( k9 P; C - bzero(&server_addr, sizeof(server_addr));
; e/ p, a O! u% H - server_addr.sin_family = AF_INET;
^8 [+ Z% c) d! \* } - 6 j) z- C' d3 a/ v: x$ s
- // 服务器的IP地址来自程序的参数
/ l; q, e, R# B. ~8 M5 n4 f7 r: e, b - if (inet_aton(argv[1], &server_addr.sin_addr) == 0)
1 x$ m4 V* \- @8 G - {
; m9 s+ {: C0 q - printf("Server IP Address Error!\n"); 9 D* m( d' m4 Z% A* ]5 J' D+ r& x6 }0 V
- exit(1);
, V) @6 @; H' f* l' D - } 1 Q' b( b, ?) z( U& |4 \4 q0 P" c4 ]
# S% \/ V2 q& V& N" [$ O2 f8 ^4 J- C- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT); % ~2 G V* @# X- X; N8 W
- socklen_t server_addr_length = sizeof(server_addr);
4 {: h9 v0 o7 ` - 4 D- q- k- X, s/ r
- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接
5 o; t) A/ d: e9 @; h& [- Q - if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0)
/ a$ U8 ?+ z+ u0 {; z/ I - { ) b$ i$ V+ r* Z. R8 A0 e
- printf("Can Not Connect To %s!\n", argv[1]); : G9 U. B; j2 D+ j* d
- exit(1);
0 j& e: [, z) l( K - }
# B6 p+ D+ ], H0 P$ N% m
+ L, k. i/ e5 R! T( f6 \- char file_name[FILE_NAME_MAX_SIZE + 1]; ' @ Z& F' ?# }8 [
- bzero(file_name, sizeof(file_name)); ) P H7 G3 |8 E( C ?7 ^9 f5 \& E
- printf("Please Input File Name On Server.\t"); : n5 N* l) p+ g; d! E2 V5 K+ H
- scanf("%s", file_name); ) @: A6 c" r0 |3 u& v# {
% Q+ ?4 b0 ^3 B- char buffer[BUFFER_SIZE];
% t0 o' j& q0 ? \ - bzero(buffer, sizeof(buffer)); - @. y8 d- ?+ f& l+ E K' O. }
- strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name)); 6 B' \$ g# H/ f7 M: S( P. d
- // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字 ( P4 q' D' P% I9 }
- send(client_socket, buffer, BUFFER_SIZE, 0);
" ~% ]( x% M- w8 ]. i
5 V3 [* I0 T4 I( ?, ^- FILE *fp = fopen(file_name, "w");
5 v' U) p r) v: F% } - if (fp == NULL) ! j( u0 J' F7 o
- {
! F5 \/ \: W6 N+ F7 U, `, { - printf("File:\t%s Can Not Open To Write!\n", file_name);
: F8 t1 ^1 @( W& R6 _0 V- Q2 h - exit(1);
* d# \' n0 A( f: }" l& K( U9 { - } , r% P" p% S) @! Y' i5 C
9 k, s2 ^' o: _& a4 Y1 g+ Y- // 从服务器端接收数据到buffer中 * w A$ }/ O* l, X
- bzero(buffer, sizeof(buffer)); 8 r1 y5 K% [) l, o2 e
- int length = 0; 2 A: L5 C( f ^
- while(length = recv(client_socket, buffer, BUFFER_SIZE, 0)) , T) u* Z7 n4 s! g
- { 7 o0 h( X6 Z$ w/ b
- if (length < 0)
0 }# P5 I1 }, S3 ]4 Y - { 9 j" p- v- u; c; \
- printf("Recieve Data From Server %s Failed!\n", argv[1]);
& j" m1 u+ O: p7 Y - break; , S6 G" u* K* [* ^
- }
2 Y) A c( H+ @/ C0 Q( _7 J - $ v I* z3 S9 t; b" U! T
- int write_length = fwrite(buffer, sizeof(char), length, fp);
% D# c H# Z) U - if (write_length < length)
5 M8 v; T& h w% O* T - { 0 O3 n+ a( f: u* U K/ ]
- printf("File:\t%s Write Failed!\n", file_name); 0 W* h& k- X! u9 S, h
- break; 4 y( g5 |/ N; I* N# Z- t
- }
% w+ Y1 q- {6 g1 s3 E8 N3 M - bzero(buffer, BUFFER_SIZE);
2 r* B$ u% |8 i: L" K6 T2 G - }
+ D8 ]# v9 V1 o! y6 M) ^
( w8 e, l$ ~5 }% U$ Y7 ], j* c( c. b1 ]- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]);
# P. n7 Q) t: T) G2 Q% r - 5 n- C8 }* T0 u
- // 传输完毕,关闭socket
) G+ g. f- H& C9 L1 l3 N - fclose(fp); / g* W5 w6 X* ?1 x' B
- close(client_socket); 6 \8 Z9 A& y; Y9 K# s$ O
- return 0; 3 V( |! e8 e D. O5 R6 p
- 4 Z& N8 u8 f! q4 i2 Y! @
- } 3 ~% G, Q$ w* O9 ? }
. r& [3 J* y; r# i+ B* G8 w1 Y3 o
复制代码- /*server.c*/8 T) `& T; S8 U' B" M
- #include<netinet/in.h>
8 R# B: G; K( t - #include<sys/types.h>. F1 X* m2 `! U
- #include<sys/socket.h>! n. S# K9 U: o' @3 ?1 @
- #include<stdio.h>- Q2 K9 R3 _% w$ j
- #include<stdlib.h>
O! A1 C4 y: o7 J, g - #include<string.h>
" O: i2 S/ {4 V$ S8 l" y - ' m' M) N& s4 U; Z6 K
- #define HELLO_WORLD_SERVER_PORT 6666 //端口号- }6 p7 v$ v" q0 y
- #define LENGTH_OF_LISTEN_QUEUE 20
- n$ R$ J8 D% Z |0 Z - #define BUFFER_SIZE 1024
+ D7 t. O# d& u" U7 q* Q& L - #define FILE_NAME_MAX_SIZE 512
6 E$ k3 Y$ m7 H l1 z( v: p4 q J. e - & x! k- E' D5 E# v8 K
- int main(int argc, char **argv)
1 p" U, a( S5 b! Z, d$ ~7 q - {* b: X) A+ Y+ X
- // set socket's address information9 z1 X, [$ w7 k6 e1 W, ^) R
- // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口$ L6 q3 W# a+ e' r; S" F% @9 S/ x
- struct sockaddr_in server_addr;
$ C3 Z& K) k( \( a9 t- y - bzero(&server_addr, sizeof(server_addr));
: I9 T1 y5 W# k; H# y - server_addr.sin_family = AF_INET;0 k% b5 \' P f4 L" \
- server_addr.sin_addr.s_addr = htons(INADDR_ANY);
$ V7 z! E( ~ V! z1 j9 N - server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
2 O& r* S* d/ R, k/ ^2 B - # i# E, d( `: W& P* Q: @
- // create a stream socket
+ W4 e" q5 h' ^ - // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口& n6 x6 ], @# x4 `+ s( K
- int server_socket = socket(PF_INET, SOCK_STREAM, 0);
( ?8 o# t: \2 A - if (server_socket < 0)
, I% T7 n9 {# h6 r( H - {1 {& r4 W9 j0 j' D4 a
- printf("Create Socket Failed!\n");, z5 d7 U4 Z0 B7 e5 ~& R3 k
- exit(1);- d" v; ? R- l$ M" n4 P
- }
) F8 A. K, Y3 g" W: B, X - 4 u( j8 x8 M9 [. L- F& p# z, X
- // 把socket和socket地址结构绑定
" y4 n" `3 M) Y' P; r- [& W$ O - if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))
& W6 w0 W6 F$ x9 E* V! n1 z E1 W - {
0 t: U* r. u; L1 s - printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);
9 c( M# k3 h/ ?; p1 j: ?- g, W8 C - exit(1);8 M1 h, } L! L8 w' A. {$ T" Z4 e6 ?
- }
) F/ _& I5 F4 ~# F5 Y - 3 f3 {2 R. Y1 @ t
- // server_socket用于监听9 J5 g3 R, |6 w0 h
- if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))
8 k1 h \( \0 _% {& ^8 C6 A - {, [; c. n( ?$ j8 t1 j# [
- printf("Server Listen Failed!\n");
! L! \" h/ ?4 F$ m( a - exit(1);
& R4 f5 P' W" U" J! B - }
% n& o4 }7 g p* E7 x+ x5 u - & i' T6 u. ]6 ]! P
- // 服务器端一直运行用以持续为客户端提供服务
6 `0 |8 O0 s* o2 H: D - while(1)3 l- c& S; m. m0 s( ?
- {
^% F* a% x8 }, n7 R2 p - // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept r0 h2 I7 M( c# @/ b, V
- // 接受此请求,同时将client端的地址和端口等信息写入client_addr中
6 X0 h5 S( _" M0 ]1 S" e' u - struct sockaddr_in client_addr;; K/ b- D. y1 y, f$ v
- socklen_t length = sizeof(client_addr);
2 J( s& B& Z. m4 l# A% _ - % ^! j) T, ~) W" {8 Q4 T
- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中
' j9 [& R* g/ F8 J1 {8 q1 [* i" ^ - // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以
+ n4 G* q! l( ? - // 用select()来实现超时检测. ~- f, J7 p o. [- y9 o' c
- // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信
( W3 R! z" C. L - // 这里的new_server_socket代表了这个通信通道. L: g5 ?" @3 g. @: P: u
- int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);2 A- e5 O o& @* v, Q
- if (new_server_socket < 0)
* N$ R% q' G7 f+ x+ s3 `$ \# X - {5 T0 ]% W& V+ B0 ^& A3 `$ y
- printf("Server Accept Failed!\n");6 J% V; N+ v6 n& Y3 X2 U3 }: t0 ?" F" J
- break;
% L* Q8 y. a4 l: b y - }. V1 i2 s$ ]& V& t
- q( U% @$ h& m4 e7 g
- char buffer[BUFFER_SIZE];( f6 w1 k/ A/ S% P( \2 N
- bzero(buffer, sizeof(buffer));
" T2 T; o _: p2 B" u c - length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);
" n$ r1 l% r0 S0 R5 g0 {0 w - if (length < 0)
$ Y7 X! l, _2 H- Z- R3 @ - {
1 T. @3 T2 R! e$ n! V* I - printf("Server Recieve Data Failed!\n");
! _ y F2 S( X+ z/ s! e - break;/ h' k. v5 }6 B8 J- b" |2 z! N5 N
- } C& D& A/ x, ]+ D0 H- J: G$ ~
- p6 L1 ]* d S1 F- J
- char file_name[FILE_NAME_MAX_SIZE + 1];
. b; H! W \9 ]! U7 T0 B _7 R; G. v - bzero(file_name, sizeof(file_name));
" d# \* [+ E+ B5 j - strncpy(file_name, buffer," w7 p& N% H T% F; ~
- strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));- w6 w( u% S- U) z
- 4 P; d9 Y$ w2 u4 I
- FILE *fp = fopen(file_name, "r");
) [$ `- T* b, g8 X( ? - if (fp == NULL)
: R1 m/ c7 g5 s" Q! Y& y7 K1 d. @ - {
5 e: g% K d0 d& w8 J0 y+ Y - printf("File:\t%s Not Found!\n", file_name);
3 b) M% c B- h5 R. ?$ G - }
5 l! Q) L( q+ k! k2 h2 X - else
& R, j! K& R# e8 v0 u! ~ - {
- s- l; x4 P f! a$ ~! d) z) Y" s - bzero(buffer, BUFFER_SIZE);
& S! i: Z: C0 K. w - int file_block_length = 0;
$ Y+ W" r } [7 F - while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
. X, S% m9 W( g4 I - {
5 q$ P& _7 l. p9 J% D - printf("file_block_length = %d\n", file_block_length);+ f! x! g& f1 C
* {. _4 r' d4 o7 r# A, B1 B- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端
F: [ y+ s" D! h& t0 f - if (send(new_server_socket, buffer, file_block_length, 0) < 0)% V+ U+ V+ q, z+ B) i; Y
- {& o6 k# ]; }3 |" B9 d1 H' `/ B
- printf("Send File:\t%s Failed!\n", file_name);$ W: Z' A. u1 U) ~# d/ j, @. `
- break;
7 ]1 r3 r: g* n' J" {' e' j - }
1 C: V. s) o5 V( c' t8 u - 5 B+ Z' |4 d) n* g" b
- bzero(buffer, sizeof(buffer));
/ f/ S4 ~/ i7 x7 r+ K1 H4 s* [ - }- ~; X" k/ B! f' Q% E8 u
- fclose(fp); ^$ j4 k. Q* c6 K6 D) Z
- printf("File:\t%s Transfer Finished!\n", file_name);& z5 R6 q) Q$ l3 I8 D( _
- }
* G8 x' J" b6 F& z$ u - ( J' p5 u/ P9 E
- close(new_server_socket);/ b$ O8 ~7 m& o' V. q3 M D
- }- J% H/ u* R; [& C9 r! b
+ o! }: G1 l2 O6 C" |! V/ m! B @- close(server_socket);% X/ v% f& b2 v0 |# _) M, l# A' A
- 2 b: t1 F" o+ f( E. D
- return 0;
# W+ Q; F& a3 h) v. ^ - }
- ~5 y! L8 }$ r8 z* i8 J) R0 F
! T; @3 K1 x5 D G/ d
复制代码
5 n4 r2 I3 b& r: k4 Q9 ?8 d0 N" s
/ v1 u1 z9 r6 N% Y$ m/ n5 o0 T& T& ^- o! z
- M+ o* }- C5 I |
|