管理员
论坛积分
分
威望 点
贡献值 个
金币 枚
|
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段.+ T) q# ^ S F. a a
- /*client.c*/
# P. n+ q A$ E$ A - #include<netinet/in.h> // for sockaddr_in / c* K1 p/ C" T5 f
- #include<sys/types.h> // for socket
5 y" y1 w! T6 m - #include<sys/socket.h> // for socket
) N( S4 l, M" L* `' N% R; Z - #include<stdio.h> // for printf
+ {2 }2 a3 ]; b& S0 n1 N - #include<stdlib.h> // for exit
( `0 R) {. k2 ~- U: B- _ - #include<string.h> // for bzero * I% b$ A2 [# \' a
- ' R5 ]; D/ H7 {6 A3 u% h* O
- #define HELLO_WORLD_SERVER_PORT 6666
1 I0 e8 D4 q+ q: M$ h - #define BUFFER_SIZE 1024 7 s& H4 e1 t" z: a: K
- #define FILE_NAME_MAX_SIZE 512 - e6 X! Y0 T' s+ [
- `) n( u+ M9 i# w
- int main(int argc, char **argv)
2 @4 L. G2 |: | - { 3 @% m# G0 Z8 w% l
- if (argc != 2)
) c, A2 o8 K8 Y/ w6 g2 r - { 5 X, b* l- Y$ X: P! A
- printf("Usage: ./%s ServerIPAddress\n", argv[0]); : x& j A4 l" Q) W
- exit(1);
8 @9 ?3 [8 g" Z4 o9 I. A0 ^, Q/ k - }
% v% H3 f# ^. s4 [: {# w
: n6 F" u8 Z2 h1 n8 z4 A- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口 1 D8 s* m: s+ u/ T) X
- struct sockaddr_in client_addr; 7 p3 Y8 ~4 l& H0 D6 p
- bzero(&client_addr, sizeof(client_addr));
" h( ^, p! e% l& T - client_addr.sin_family = AF_INET; // internet协议族 * t4 B9 Y8 Q, T5 [( `8 U# B
- client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址 . X- u1 k' W5 ~( `3 @
- client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口 ( {: j: _$ U: C2 v6 l4 M
* J# B: g" v( P! C$ q- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket
$ J% Z; z- \7 k9 r - int client_socket = socket(AF_INET, SOCK_STREAM, 0);
; u& \1 M4 l: G1 c6 W - if (client_socket < 0)
0 n. a" x* ]+ k1 ~; K, W! M# n - { ! g6 W ~7 a& {' B |3 L
- printf("Create Socket Failed!\n"); 8 d- w% K1 N6 J* s3 ]$ f* ~
- exit(1); / A$ R9 W- R6 N8 N+ _9 z/ j
- } ) ]$ Z6 `$ x2 y* }$ e
" J9 R" m4 @9 M' _! r" m- // 把客户端的socket和客户端的socket地址结构绑定
' \) b" y+ d1 c: _. e% p - if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr))) 4 U8 M/ j, p3 c4 w
- {
: n2 e) L7 S- c- V5 o) {+ [# [ - printf("Client Bind Port Failed!\n");
2 I) \# v, k) P# X - exit(1);
. }# K' v3 w0 z9 A" S( ?% ` - }
; M, o) @. f5 t* v+ c3 I
2 S* W @7 Z0 w4 l6 z- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口 ) `4 a: x( N+ u* m( P
- struct sockaddr_in server_addr; 1 K. T) a- }0 v0 R
- bzero(&server_addr, sizeof(server_addr)); ' S6 j1 ^/ i# n! I H: M
- server_addr.sin_family = AF_INET; ; ]$ u4 [+ E" U1 p4 d+ }9 N7 w, t
- * R' P9 |2 r* W& P
- // 服务器的IP地址来自程序的参数
5 ^% W$ |' c* D+ y* l: E1 m - if (inet_aton(argv[1], &server_addr.sin_addr) == 0) 0 f. @- d! Z4 |
- {
3 @& O5 b2 _$ R - printf("Server IP Address Error!\n");
/ z8 g- N, a4 B - exit(1);
) T3 q; U% r. N9 H) t' y2 { - } $ s. E% `2 p, U6 R% U1 @
- a( B; w( r. }! l% T* h t
- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
G9 N1 u* |0 G- t7 y& y; W# n - socklen_t server_addr_length = sizeof(server_addr); % l4 d7 q" _. f! u
2 ^8 G5 E' `: J5 m! U) }0 F- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接
3 v/ H. Z9 s% K - if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0)
, k8 A- w9 ~9 [/ x: s+ K- \0 ] - {
& F+ ]' A) ]" g) ^, ^4 p - printf("Can Not Connect To %s!\n", argv[1]); 8 W: S2 U3 i) |- Q+ _% C* G
- exit(1);
L( B) c& [$ n Z D$ m - } ) Y' X( d; `. G8 n$ e6 d9 R$ Z+ j) }8 M
5 M! R( K/ K r( a2 o9 U( f4 Y- char file_name[FILE_NAME_MAX_SIZE + 1]; 6 U, s* \- D2 h5 t# H3 G% t/ R# V
- bzero(file_name, sizeof(file_name));
* _! Z( B! k+ [8 Z0 G* { - printf("Please Input File Name On Server.\t");
( I) g7 `9 y7 A! {# D - scanf("%s", file_name); # W# |% J/ A0 |) ~
- 8 h' r* y: D. _3 Z( ]3 v; N
- char buffer[BUFFER_SIZE];
+ [% T3 T0 s! w1 Z: ~ - bzero(buffer, sizeof(buffer)); 1 k* F: c2 O: X' h
- strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name));
1 s( B. j7 T+ Y6 g1 R C$ { - // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字
3 k. b8 H1 h! L* X9 i" e - send(client_socket, buffer, BUFFER_SIZE, 0);
: B0 }+ h+ ~; j0 K1 q - 9 p Q' a5 @' J# X) A8 Q! I* @0 t
- FILE *fp = fopen(file_name, "w");
& E0 p0 ~2 w1 E1 j, t5 `( G - if (fp == NULL)
7 r+ G) o, w. Q h- k, x* R - { 7 _6 } ~, V6 B" ~6 x+ K
- printf("File:\t%s Can Not Open To Write!\n", file_name);
3 Z% e$ A! }& M+ T4 o - exit(1); 9 T) n+ ]) g1 u# O
- }
, O: c' F$ n) X* F" ^: ~5 p
% @5 w3 s0 Q5 A- // 从服务器端接收数据到buffer中
% n, E. O! L- c* L& ?8 c8 R - bzero(buffer, sizeof(buffer));
! o+ f0 \: E& } - int length = 0;
" q" z% m4 E# f5 Y! N/ f: \5 S - while(length = recv(client_socket, buffer, BUFFER_SIZE, 0))
: ^& X/ I: z2 {; F, ^) u7 y - { , z: q! Z. _: [; r. I
- if (length < 0)
# T W$ M% t. p5 `, B0 k3 K - { 0 x! }) G3 ]- m8 m2 V8 U+ S
- printf("Recieve Data From Server %s Failed!\n", argv[1]);
5 X" v8 A2 d* x& Q3 ^/ A. k - break; 9 r) q8 d( V. N* W. H8 ^/ o1 U) s! Y
- } 2 p) }0 k" \6 K, M; r
- ) M- b$ f# Z: w4 l: w
- int write_length = fwrite(buffer, sizeof(char), length, fp); ! ] u: {7 V- H: G$ `7 G
- if (write_length < length) 5 k0 S6 w% z) F
- {
1 u& h- L. s) p; k8 Q6 g( O - printf("File:\t%s Write Failed!\n", file_name);
9 R! T2 K& j; ^5 s6 h( L" }- k; n - break; ) G8 @- i$ R6 S, g7 R9 T; k
- } . O: d* ~, y5 H1 } Y
- bzero(buffer, BUFFER_SIZE);
% |1 h8 X# o. R! Q. [% k' f8 O: F - }
6 Q4 F6 w1 K9 s$ h. d7 p& U - . o. l( C$ \/ m4 x+ l: h
- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]);
1 h; p! ]% F% j! |$ @
# I3 C! v4 u; X8 @: A: U7 H- // 传输完毕,关闭socket . d9 R4 \" i9 H! M
- fclose(fp); 8 m5 y Y5 ^: l: i4 f
- close(client_socket);
8 o( G0 T8 {3 N# {. W9 O - return 0;
# Z# f& _6 n$ @8 Z; W: p/ g& l - ( W$ w( S, [/ R# I- h3 e
- }
& K8 D7 z0 ]7 `2 f/ `3 V! j - * G- P5 L( U' Z Y2 D9 k# x9 l- a
复制代码- /*server.c*/
d; I n' s7 s( j9 j - #include<netinet/in.h>
# G4 N' O1 p5 H; `- C6 A( ^ - #include<sys/types.h>
- u' l% o* Z! I" Y - #include<sys/socket.h>
% v' v: H5 V* S# c7 |, i - #include<stdio.h>
" Q" d! a1 c( t& d) G! l0 V8 i d - #include<stdlib.h>
8 ^+ {2 R, p3 P3 L0 g* ^" P - #include<string.h>1 e& g9 p- ]3 J+ Q$ t6 y
* K4 h n' q2 F2 u! n- #define HELLO_WORLD_SERVER_PORT 6666 //端口号
" \1 y6 ?. ]# I$ ^& p - #define LENGTH_OF_LISTEN_QUEUE 20
' N; z6 V$ e8 Z) e; a8 _, c( h - #define BUFFER_SIZE 1024 C; B7 } V6 E( y) V5 K
- #define FILE_NAME_MAX_SIZE 512- t5 x" ?) v ?5 ]$ _: T
3 E0 I4 X. V. C8 H) ], }' T- int main(int argc, char **argv)
+ d( I& R$ K( y: p9 L' E - {1 X0 B6 Y. D$ y0 x4 l' L, L
- // set socket's address information
( N0 e# C# H0 ?" H% y* v - // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口
* Q- d& g. v* \; Z+ u# _ - struct sockaddr_in server_addr;
4 G u+ P% n) U4 _8 v7 ` - bzero(&server_addr, sizeof(server_addr));
% q0 B3 X' D; n2 \" D) R7 J, v - server_addr.sin_family = AF_INET;6 k# r! ^# u3 _/ Y0 h% G
- server_addr.sin_addr.s_addr = htons(INADDR_ANY);
' T; Q( |! n( j - server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);- `9 p9 [4 x1 Y$ o9 i# i n
4 H& d3 k8 J, W {! |# {# o; v5 _! J- I1 b- // create a stream socket
9 q A. C7 v6 K9 F3 j7 l& Y - // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口' A1 S+ X6 ^- R) j
- int server_socket = socket(PF_INET, SOCK_STREAM, 0);# T7 p( l8 N" C! a, K; ^
- if (server_socket < 0)
) t+ t/ k9 f, u - {
+ [3 q. v# R1 _ - printf("Create Socket Failed!\n"); H+ H8 _0 h8 g% u) G: R
- exit(1);' P: }& q7 ^" ]4 r
- }$ R v3 I$ f1 Y( \
- # k5 s" u; q g1 z" f
- // 把socket和socket地址结构绑定# a% J5 ?7 e( H1 R
- if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))
y" K1 `" d5 X/ u2 R8 } - {& |* R, T% U" `: Z8 K( E
- printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);
- I e& B, H9 f' j - exit(1);
+ S, N8 L+ C2 {- n6 [ - }
$ `7 c3 S* t5 t! w5 U' n0 o( Y - 6 x3 E, o4 P) _1 a. ^5 j7 @# N
- // server_socket用于监听0 W& K) o8 ]( J/ a, {% W
- if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))+ F/ y3 x6 S& T) U# z
- {8 j* w3 S8 d! H8 V
- printf("Server Listen Failed!\n");1 I2 F1 L6 r) z; O6 D0 i @
- exit(1);8 a! K* W0 h# J, q) q, {5 ?* D/ L
- }! c# c7 ?0 Q/ |4 }+ r
- 4 Y$ m% x' q/ I3 Y0 o0 n
- // 服务器端一直运行用以持续为客户端提供服务
( |1 s# M% K, ^" f G1 P - while(1)
4 t [2 |1 k) F* r! b; p% t - {- H1 o$ h$ x" f A
- // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept4 b" ]: W8 C7 }# p, A3 }& F
- // 接受此请求,同时将client端的地址和端口等信息写入client_addr中
" {) g* J9 g( j* z/ M1 e - struct sockaddr_in client_addr;" X, y5 r% O. {$ {- T- w: e& r
- socklen_t length = sizeof(client_addr);' c+ f4 P# S( `) K$ j5 K
4 w; X$ @7 w+ C0 X& e5 x" w- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中
. H+ i' v) G- q% I - // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以
' _/ L5 I, h$ d- z$ U: I- G0 b - // 用select()来实现超时检测3 r! k0 l; U, u D5 x% s: i
- // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信! ]* C2 k% l3 o1 s w5 P8 H* {
- // 这里的new_server_socket代表了这个通信通道
3 G) D/ N$ N) Q# q1 X7 U( T - int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);2 Y- H6 E( [* u! ^+ U2 X8 s% {
- if (new_server_socket < 0)$ D# m3 v' ]- S9 P- z
- {5 [: S1 }3 z: a" U' J1 {7 ~1 `1 a
- printf("Server Accept Failed!\n");. E2 S) `& m/ I' G( Y: Y
- break;
7 g: O$ Y" l. s7 C( J5 J - }
: s! P! Y2 P5 f% ~+ t - 2 T- l$ a) v3 {; w: ^% F! M
- char buffer[BUFFER_SIZE];, c3 s- O. V1 J! o+ C" d
- bzero(buffer, sizeof(buffer)); T! s- u; m' _+ K R/ G
- length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);
/ _* d/ o7 `9 j - if (length < 0)
- |# l8 I- Z! a K2 u. x1 N - {
6 k6 t1 N; Y( R. E6 l - printf("Server Recieve Data Failed!\n");! t" f- U5 g- O& X" E( ?! S) b1 p) R
- break;
9 T. \6 B% k' L% i) f - }
( M0 |$ Z* v# F
, P# @' o( k, J6 W5 [. H/ g% x" _4 k- char file_name[FILE_NAME_MAX_SIZE + 1];% ?7 H& f3 B( ^% J! b/ s# P
- bzero(file_name, sizeof(file_name));7 K. z. d' ~+ l# P1 U7 n- [
- strncpy(file_name, buffer,; A# X; ^8 |+ S
- strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));# G6 J$ W6 M* J- Y6 k9 D+ J* E5 b
* b) W0 i' K' H2 X; l) z; a- FILE *fp = fopen(file_name, "r");3 @3 M ?) U% M
- if (fp == NULL)
6 ~& H' |7 e6 M9 c7 o - {
" {2 _5 k- G. r: ]* n2 e - printf("File:\t%s Not Found!\n", file_name);
7 x% V) n) |, M9 a7 I8 y5 e" b" C - }
( I* f! _$ o! t, U# p# L8 |( c - else
1 h" m, P$ u3 B) j& S7 f% k8 {- Y5 \ - {
" F, c# ~8 J8 [7 R/ f$ l - bzero(buffer, BUFFER_SIZE);5 W2 B& G9 F Q2 N
- int file_block_length = 0;& F3 f: r+ {. y
- while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0). T2 u: L4 [3 E0 G
- {
( f2 W1 c3 p- C7 R, u - printf("file_block_length = %d\n", file_block_length);
7 x* n& v- r" G7 E
! T: J9 _; @5 A. e% q {( p N- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端' K: @ @0 Y/ ^2 b& E
- if (send(new_server_socket, buffer, file_block_length, 0) < 0)7 U8 L: G4 s4 b$ h3 Q, s1 ^
- {0 K, U2 K( I! a* S
- printf("Send File:\t%s Failed!\n", file_name);. P5 U6 x- B' u1 L2 c: {
- break;
% `! F( I8 x# ^8 h2 z. j, ]; u - }
% T7 B( Q) R" g7 z9 x+ M0 I
! \) E/ ^9 I+ C' A6 y( @, v- bzero(buffer, sizeof(buffer));- |7 Q& M: E: \8 D4 ^
- }
: E" S: }* r7 l+ @8 x6 ` - fclose(fp);) E3 v+ z2 S& h9 H6 D; l
- printf("File:\t%s Transfer Finished!\n", file_name);* ?2 R; t7 K Q
- }" W9 u! I$ w5 s1 F% M3 E* y
' `: p$ x% J0 Z1 @' x( I( c! P- close(new_server_socket);- x+ u6 u! h" `- a5 a
- }6 Z& ~; I$ q7 L" s, i' b
4 v" X. r+ |4 O( X- close(server_socket);
4 U7 n* a( M- A) A9 \2 i - ; Q" N) @0 h! l
- return 0;
5 p5 s5 l! r- t - }) M, \' F- Y! }% Y* m3 g3 @
( g; a; K+ i! c8 _
复制代码
0 r/ H9 r' I1 u/ l+ ?$ ^, _2 k+ S
5 b5 T7 q4 x3 ]9 Y1 j6 b
& s+ V; w( [" o |
|