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

楼主 |
发表于 2020-5-9 01:48:09
|
只看该作者
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段.
# s) P6 I5 a7 m4 C5 Q8 o- c- /*client.c*/
4 m6 p* G+ `! |8 s- x7 [# C8 r& B6 O+ Z - #include<netinet/in.h> // for sockaddr_in
6 Z0 n8 B" Y! I7 a5 o - #include<sys/types.h> // for socket $ O4 b( ]" O8 \' S
- #include<sys/socket.h> // for socket ! L) H" U4 o" u4 Y& E/ Y) U4 K
- #include<stdio.h> // for printf
; c" k: Z P* l - #include<stdlib.h> // for exit 3 b: v% c7 m- u7 l" ^8 E, J
- #include<string.h> // for bzero
: Q* t" t; b/ `2 M6 o4 \* p) h - + t* s1 S4 J0 c
- #define HELLO_WORLD_SERVER_PORT 6666 3 v. K& Y' X7 f% v/ k8 a7 z5 K1 n
- #define BUFFER_SIZE 1024
6 _0 J% w0 F' ]/ @* A - #define FILE_NAME_MAX_SIZE 512
1 h$ g2 X9 }/ Q: S/ K: @
' y) L' v- D" t7 a s; k- int main(int argc, char **argv)
8 ~# D3 q, Z$ a - { , o2 U; o( ^0 v* s
- if (argc != 2) * Y4 L R' ?7 D U7 m, c
- { 6 o6 g( x1 \2 S$ K0 K
- printf("Usage: ./%s ServerIPAddress\n", argv[0]);
# T; O, I0 g$ x - exit(1); 3 Q2 A' t+ x8 w5 X
- }
2 U3 Z5 J/ ?4 n
; o& Z; N. d7 O" g- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口
: }) b# }* ~4 z: d4 O0 _4 v% [% ?5 ~ - struct sockaddr_in client_addr;
5 Y/ @! a( Z, h1 `; t5 m$ x: S - bzero(&client_addr, sizeof(client_addr)); * R: Y6 n) }7 Q* [, k( e
- client_addr.sin_family = AF_INET; // internet协议族 V! d% l7 D U% }# w: F& N
- client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址
$ u$ Y& S Y' V W - client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口
. T; R8 X+ |, c! `) F% H# `* s; c: W
) U* G& n- T' r% X5 f1 ?, S! O" R- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket
0 I4 x ?$ h' ^, h - int client_socket = socket(AF_INET, SOCK_STREAM, 0); - g; X- l0 d) D& z& C" K
- if (client_socket < 0) ' J: Y' ?: v. k8 j- H" k, v/ Y7 D5 c0 |
- {
8 Z9 f1 s8 T$ d, N- B9 c - printf("Create Socket Failed!\n");
* `; e5 U3 I# @9 G - exit(1); & _7 _! V }& g2 V2 g0 P4 O3 r
- } 4 J! J1 U) U+ o* \7 e V
- 9 C/ y+ x& T; }8 R, d7 i
- // 把客户端的socket和客户端的socket地址结构绑定
; t, y8 N+ L A0 d - if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr)))
4 K1 i0 z3 ~& P1 a - {
( O% {7 ]1 f% q- T% t - printf("Client Bind Port Failed!\n"); % l+ a6 c, Y$ K9 _- X: c
- exit(1); - f" g9 b3 C% R o/ ^
- } 8 a* \& i/ C/ N" [' H9 C4 r1 \
- 4 W8 O5 }1 _( T: l( Z
- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口 3 [- s' Q1 D& W2 M
- struct sockaddr_in server_addr;
+ e- i5 G& A9 X3 O& g- x5 L - bzero(&server_addr, sizeof(server_addr)); ) O& f; o+ W/ ^. q* [
- server_addr.sin_family = AF_INET; : L+ g F- A( e' x1 L: f
- - X9 Q t- S4 m7 |1 X o
- // 服务器的IP地址来自程序的参数
8 I5 w2 m/ S1 S; K - if (inet_aton(argv[1], &server_addr.sin_addr) == 0) ) L0 m! S- i. i5 l6 [( S$ M) i8 Z3 x
- { 6 Y6 R, j: X9 @" Y) l' z" E5 h9 o
- printf("Server IP Address Error!\n");
8 y/ F6 b3 m+ L2 E3 [6 X - exit(1); 7 n: ~2 _; g8 k" i) W
- }
/ [( _: {2 V3 P+ D( x$ C8 }+ p+ ]3 R( d2 u
& M7 ?" H/ e7 U; O8 }- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
4 l/ d( |' c) ~ - socklen_t server_addr_length = sizeof(server_addr);
! `3 `- V- v; ?0 a
. K5 c- ^3 S1 b! t1 L- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接
0 k% V, s; r* R" t7 ~ - if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0)
' I& l8 _# n+ N1 |4 a - {
\; }8 M# p. U D0 [( a - printf("Can Not Connect To %s!\n", argv[1]); + j4 D2 g' o3 t7 y0 H
- exit(1);
) y& B- p0 _5 y3 D2 `, K - }
- q& G: P0 n8 n8 {3 x
; `" u1 m- O6 R9 ?, U8 U- char file_name[FILE_NAME_MAX_SIZE + 1];
6 n3 g' n0 X) R! p - bzero(file_name, sizeof(file_name)); 8 F% e a" G, ]
- printf("Please Input File Name On Server.\t");
/ c4 H7 i% j2 k9 B4 ? - scanf("%s", file_name); / x9 Q" m9 z3 f( D
+ D( X+ Z- H* x- B7 O9 u2 x- char buffer[BUFFER_SIZE];
6 I$ v" o2 z. {, f& { - bzero(buffer, sizeof(buffer));
7 i: w( \6 |2 k+ Z7 t - strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name)); ) `, l2 F6 o5 k9 d
- // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字 1 g: L" d% ^ C9 @% s
- send(client_socket, buffer, BUFFER_SIZE, 0); 5 X' `' j" S1 D
9 }0 H4 S) X# K6 y8 ~& M. f- FILE *fp = fopen(file_name, "w"); ) O) j0 X& x# C# D
- if (fp == NULL) # Y2 ~$ E5 u* d M
- { $ P( G. A* `$ k. _- H
- printf("File:\t%s Can Not Open To Write!\n", file_name);
3 b1 ^( L) K* R' ` - exit(1);
0 ~$ I" [6 f/ { - } ! E9 n& R& G" g
( j& V' D5 f3 A8 M% N# z- // 从服务器端接收数据到buffer中 6 e4 k' K) x. A1 }4 f
- bzero(buffer, sizeof(buffer));
! F) }; p# x6 F9 `2 h/ }# X8 K - int length = 0; 6 l. P5 |6 @' L2 O: ^' t
- while(length = recv(client_socket, buffer, BUFFER_SIZE, 0))
9 J8 ?8 }% A9 ]7 V) Y - { 4 |/ U* E$ l& `, r# L
- if (length < 0)
: ~3 b. R, `- x& |" ?8 ?9 J5 ] - {
- |" ^3 R6 R0 b. K) i* f - printf("Recieve Data From Server %s Failed!\n", argv[1]);
; s9 j" R9 l! ^) |$ T. A t - break; 6 R: h. c5 `- v( _ X
- } : y1 i) I% u1 Y, ^3 f% ~
7 ^1 Y0 o) p2 R- int write_length = fwrite(buffer, sizeof(char), length, fp); : X4 l) _; L" N, M0 N2 c B
- if (write_length < length)
/ Y" [$ D0 K. G4 ]% m - { + C& V! d* j }& H- Z- t; Q
- printf("File:\t%s Write Failed!\n", file_name);
3 Q- _ z% A3 |4 a - break;
( s o# _7 n* d4 w* C0 P - } 1 ~ H5 K7 T6 h+ }
- bzero(buffer, BUFFER_SIZE);
7 N1 | d. `% ]& s E - }
5 W8 F8 h7 ^3 M* ?1 U
) e/ Q1 B+ ?; z0 r1 g/ h- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]);
: u7 n' ~7 t) M - 0 d$ q* S5 h+ X% g' J3 d
- // 传输完毕,关闭socket
# r }# F, h% F# S& _* Z - fclose(fp); # o: f, `, z V2 W- K3 W& }+ u# e
- close(client_socket);
' R: `4 J- {9 t; r6 C4 E0 Q - return 0;
% T: \+ h* s- o1 v; H9 V* \ v - 4 l/ }# _; Z- L
- } ( b* T& I: S0 M& d
- * F) D5 C3 q9 R: G: I
复制代码- /*server.c*/1 l8 v0 N& F& G, w
- #include<netinet/in.h># D# P- v+ m, G1 a6 m
- #include<sys/types.h>
1 O" ~- ^5 l1 p# h) k" f - #include<sys/socket.h>4 n( ]7 ~& W+ j* q
- #include<stdio.h>
# d8 B. v, \: ~1 R; h - #include<stdlib.h>3 ?/ y( n# g# u" k0 u% p) B
- #include<string.h>$ n- q' X. {. U2 {" }
- G5 q, _: {4 H* u4 l! C8 J- #define HELLO_WORLD_SERVER_PORT 6666 //端口号3 @: t: @1 m) |( b
- #define LENGTH_OF_LISTEN_QUEUE 20
7 \; r* M: M$ I* ^3 F N% e - #define BUFFER_SIZE 1024
: Y' n* R. k, a& v' L - #define FILE_NAME_MAX_SIZE 512& e# Y7 |2 C w1 g( |: E& r
- 8 l: q! }( P0 h0 @: f
- int main(int argc, char **argv)
5 X3 h' {6 q& Z" S - {
. c1 e7 m9 n. Q' E9 C+ u2 Y( X3 g - // set socket's address information3 Z1 j5 A( Z$ r5 N$ Y. z4 V
- // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口
& a2 ^$ T0 z8 |' k8 @ - struct sockaddr_in server_addr;/ i3 F( h! Q, Z, O4 G2 n
- bzero(&server_addr, sizeof(server_addr));$ Y b; I$ ]9 \/ r+ \: T ?
- server_addr.sin_family = AF_INET;
# G8 D) g0 Q3 S9 O2 R5 @7 ?3 M - server_addr.sin_addr.s_addr = htons(INADDR_ANY);
* s- \# a1 m5 Y" b) a3 D - server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
' i4 s* X+ \9 O3 c - 6 J8 r, M/ f' r8 @: A% T
- // create a stream socket
/ f$ ^( X! W/ [3 C - // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口9 f) h- d' _/ s- H7 ]: ?
- int server_socket = socket(PF_INET, SOCK_STREAM, 0);
) u2 C& d- a2 I& ]3 a/ @ - if (server_socket < 0)
3 F" |. N- y7 c7 H( T8 L# Z - {/ y. t4 }+ ]7 ]* B0 R6 d
- printf("Create Socket Failed!\n");9 m( M' y( w! Q! C1 Z5 T; X q t' T
- exit(1);& A3 i8 g+ |. |
- }& R; \+ K: o) ~, ]( y6 i
7 x6 Q/ ^- p' ~. a, T- ~8 j* i, q- // 把socket和socket地址结构绑定
3 H4 ?4 P S; |+ e5 \ - if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))
6 x& q& K' m) ` @- }9 h3 U - {
, N) n6 J& Z3 O/ | - printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);. D8 o8 ^, D1 \4 [4 `
- exit(1);
- [7 ?/ k% |0 P) i; ~5 U/ _2 z - }
& S8 q# F& h! V. L0 a, I - & ~" N/ _2 j* @" j: Q2 w
- // server_socket用于监听% m$ a1 h% b3 B- f$ n$ k6 k
- if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))" o5 v! [" i' V6 R# O4 l
- {
& ~/ Z& {+ D( E/ S/ ~# i - printf("Server Listen Failed!\n");
7 n6 a% z% ~) A) l9 W - exit(1);9 W0 p9 J- E3 Y& q/ ]. r# V/ h; R
- }4 F! g3 C8 |, H
! [/ T9 c- {$ s4 _- // 服务器端一直运行用以持续为客户端提供服务
5 _3 p8 I |/ z/ ? } - while(1)
$ D0 c8 A8 [2 `- y7 k& S5 t9 M. ` - {7 U" g" z8 n8 f! C4 K( V. O% @
- // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept. M+ Y2 ?& Y, k7 v. r: h. O, X
- // 接受此请求,同时将client端的地址和端口等信息写入client_addr中" z/ m# Z [) E* W7 X& F
- struct sockaddr_in client_addr;( }1 U% y9 Z* \9 N
- socklen_t length = sizeof(client_addr);
3 b* q, b/ q) n* G - ' `& `) i5 a2 i- S& A( X" C
- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中5 j" c9 {0 p5 A5 P1 r
- // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以0 K2 e" E- N0 J% ~: m6 f+ E0 _
- // 用select()来实现超时检测
7 A! [0 n: m( ~5 S4 F - // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信/ o p& |' l |6 V
- // 这里的new_server_socket代表了这个通信通道
, i% [5 b3 J' ^& ]/ Z" z - int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);( d3 R' i3 b X4 V+ [2 @7 r
- if (new_server_socket < 0)
% R8 O* }* n" h1 B/ M - {
$ K, c, o. K, l4 n - printf("Server Accept Failed!\n");' s9 t B; _1 j! W) M$ H* ^
- break;
" @% k( H7 r& h" w/ f. c - }
3 }0 F9 {$ ?4 G$ |$ w - 1 Z$ v: O9 ~* c s% g( a
- char buffer[BUFFER_SIZE];% W0 u7 T, b# q C5 k
- bzero(buffer, sizeof(buffer));
g. e, O: t0 x& s - length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);
6 L- r8 l0 J4 D, ?. e0 p1 @ - if (length < 0)* g" ~$ Q" X, b, V( P. i; ~( [/ h$ G0 | i
- {/ q. e4 V. G% K/ U2 G, |
- printf("Server Recieve Data Failed!\n");
; k% J% P' U7 M6 N. X3 ~* y% P - break;8 O0 t3 ~4 C8 k% Y( [; e
- }
! k- n {/ p% {( b5 `6 P - b4 [% e7 Z4 E2 H
- char file_name[FILE_NAME_MAX_SIZE + 1];: p/ _7 i. t" P4 f# M6 t* s
- bzero(file_name, sizeof(file_name));$ F p$ |) _% u$ m e4 L
- strncpy(file_name, buffer,
$ T; o: w0 G& f( X - strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));+ A! v2 N0 v1 w7 @8 G
; A6 E3 [* P% h- FILE *fp = fopen(file_name, "r");
0 N1 I: ~( u1 d& t* }5 A - if (fp == NULL)
6 I0 q$ z, @* j W5 R4 e - {) T2 ]$ ^- K0 ?( D0 l# K, M) M3 P
- printf("File:\t%s Not Found!\n", file_name);
! B- ]& w6 c& p! t# E - }' _( b/ j4 u3 {, {
- else
7 v8 ?! F+ E& H" b5 n# o# t0 y - {
5 x6 C! ~# k4 }. @: K3 w - bzero(buffer, BUFFER_SIZE);* ^# Y! S7 O: W8 O' p
- int file_block_length = 0;9 N4 g) d: \. ~4 ^" O
- while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)& D0 N; a A9 |. w
- {
; S0 z! z8 K( `& G7 ~( C& e - printf("file_block_length = %d\n", file_block_length);
- J$ Q7 ~1 Y' x( v% W3 e - - Y5 \! K( O% e( _, |; I! Q9 n
- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端
! M) @+ B8 s S" b - if (send(new_server_socket, buffer, file_block_length, 0) < 0)
+ U V5 @" n- K% N6 N/ d - {, U+ C5 R- R2 P' I# J. F
- printf("Send File:\t%s Failed!\n", file_name);
1 l) z( ~' j( m# _7 y' E& Y - break;
) n" m8 r+ A% r h* J. z - }& G# x$ U1 @- ?0 u* {" t: x
- 0 g" a6 u% w& C
- bzero(buffer, sizeof(buffer));
! U* ^! e: x; ?8 ]' [* ~ - }5 u& V( [9 X" d( @* A/ J
- fclose(fp);' k" S% I' h" H) b# x
- printf("File:\t%s Transfer Finished!\n", file_name);
4 x( |& J& i! Y& }/ B1 @6 J& R - }9 Q7 i. W$ t& s( g' `
! m; ]5 i2 r! W9 @- U2 B; C- close(new_server_socket);
# R- @: E5 {. e4 W& v - }0 i, C2 X) @3 a5 o {( d
- # H5 y9 j+ ]1 U {: V
- close(server_socket);$ t( A; p! q& I8 G, \$ @1 _
- 0 p2 J# k6 l1 [; t+ Q: D
- return 0;1 \$ s9 g" x, P8 n4 }. a% a# p/ b
- }9 {0 p) G9 S/ J( B
- 2 R8 C/ e" u6 n
复制代码 ' y0 `0 m" T) k, N" E
6 {+ a" q4 H) a* S
. Q4 c' j Q( O8 c/ H
: N' x8 g" t1 l7 ?
|
|