管理员
论坛积分
分
威望 点
贡献值 个
金币 枚
|
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段.$ P, F: S: u. b7 i. ^/ M
- /*client.c*/, Y3 X; A& W5 P, U1 \+ u5 P
- #include<netinet/in.h> // for sockaddr_in 5 z# ?5 s" G4 S) j6 y* b1 s' }3 _
- #include<sys/types.h> // for socket
. T% Y5 Z; ~& G2 N: z - #include<sys/socket.h> // for socket " `, ]. q( l' z
- #include<stdio.h> // for printf
t, k4 x: o) v - #include<stdlib.h> // for exit
S& p5 U% H' v9 h4 h9 M1 C - #include<string.h> // for bzero . v3 V9 f* Y, {5 |
- ) ^# d& Z2 ?) M$ S
- #define HELLO_WORLD_SERVER_PORT 6666
$ H' ?- ~" k8 I5 m/ _. V8 s - #define BUFFER_SIZE 1024 * L+ ?$ Z9 y' s( X! C
- #define FILE_NAME_MAX_SIZE 512
. }$ ]. h& y5 r; E. M6 D
8 \1 D% a# r( A: d- int main(int argc, char **argv)
' h! a( |" @5 Y8 h* [. w# A - {
3 [6 v, n" l! p0 } - if (argc != 2)
0 P! N% d# W( w5 e5 m. K - { 1 |" f3 k( a% E
- printf("Usage: ./%s ServerIPAddress\n", argv[0]);
0 z" k7 S+ L! o( X, j% O2 N - exit(1); 1 K; t0 g" b: z. o+ {
- }
% w3 E) b5 U) @5 d( Y - 7 r+ `/ S V& s% F0 g8 @) v8 \
- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口
3 Z! k. Q: k; Q: W6 Y: d6 }0 Q+ Q - struct sockaddr_in client_addr;
2 S6 _1 W% q3 ^2 V6 _& | - bzero(&client_addr, sizeof(client_addr)); 8 A1 [: v1 T: T \8 L* L
- client_addr.sin_family = AF_INET; // internet协议族 5 J8 p a4 b6 _" g5 @
- client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址 5 e+ Y: h) m3 `4 I c7 @& W7 p3 z- g
- client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口 % k( @+ }6 r/ C+ _" y3 H
- 7 d3 M: \: k3 M+ P, M# `1 J. h
- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket ' ?6 Z( h; L, X2 B( [& q
- int client_socket = socket(AF_INET, SOCK_STREAM, 0);
& c d$ f1 X; { - if (client_socket < 0) 0 D% q4 V) g% F' \
- { $ j P, K4 Y6 I6 q
- printf("Create Socket Failed!\n"); 7 k% n2 ?6 D7 ~1 a4 n$ _1 z- z7 W! v
- exit(1); 2 z! s, C5 v' \5 L9 W8 Y- @
- }
" y, R; R4 ~9 F/ y z# C9 Y
3 @, m- ~* Q/ @ T- // 把客户端的socket和客户端的socket地址结构绑定 % |/ N& q e. G' e( Z
- if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr)))
* N; j5 o9 h0 I( d; Q1 b - {
# W( K& z% X' ^/ s; i3 _; @ - printf("Client Bind Port Failed!\n");
% L1 f6 v, f0 {/ [6 D5 z - exit(1);
9 m/ [; k! a: z; } - }
# B1 p8 I' I( c6 k& \5 g7 W+ V - * G/ o# E' z) t7 `/ t
- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口 " ?, e3 N) m% o
- struct sockaddr_in server_addr;
; `/ f1 \. I) {5 x c7 b. G7 P - bzero(&server_addr, sizeof(server_addr));
4 W/ A# i& m u | - server_addr.sin_family = AF_INET;
1 h( I% M% z0 P k - 4 J6 G/ R1 `6 n% O: B+ h
- // 服务器的IP地址来自程序的参数
$ U- I9 G# b) O ?7 l - if (inet_aton(argv[1], &server_addr.sin_addr) == 0) . ?% |! G9 y# a1 B
- { - t1 W6 p$ I3 d8 K# J
- printf("Server IP Address Error!\n");
4 X& u1 X v4 E1 Z - exit(1); % n3 H: {4 p8 D1 {5 R" Z7 U; c( H
- } - B4 E) L! @. b$ x/ W2 M
# A0 h- k- I' M' t( K3 m2 i( R- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
) ?: r' o8 l- P d; v3 K - socklen_t server_addr_length = sizeof(server_addr); * s6 ]6 P! }* ^, l" ]. r7 X
- 1 p& y# m1 s2 ~$ W. \# Z3 Q) z4 ^
- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接
1 p5 k" c& N& O/ ^; l' T' t - if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0) 7 P% h- y" e4 N* o
- {
3 `" o; s+ w2 J1 } - printf("Can Not Connect To %s!\n", argv[1]);
5 n0 T5 m+ h. i$ u/ ~8 I5 S - exit(1);
4 u5 b% s8 C: X5 n9 L- c - }
; \7 f. M) U; C* Z" E
7 k& v* }3 C0 [$ ~: o- char file_name[FILE_NAME_MAX_SIZE + 1];
9 q: ]$ a1 Z7 Y - bzero(file_name, sizeof(file_name));
! A" y7 k, [( u% g& V p2 [3 q - printf("Please Input File Name On Server.\t");
) q* r3 `6 m* y; y+ `3 S - scanf("%s", file_name);
f* o w) c% K+ v - * Y7 f7 u. h. N% f5 L$ I! o
- char buffer[BUFFER_SIZE];
- Q7 b/ F4 P8 O - bzero(buffer, sizeof(buffer)); 6 w4 p# D9 W, V, T
- strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name));
: o$ N8 m) C) `, h0 O - // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字 |, f; p9 j8 i- [* `4 R+ z K
- send(client_socket, buffer, BUFFER_SIZE, 0);
, L; N; P' j. C7 ~5 b - U& R, C! \5 [. P
- FILE *fp = fopen(file_name, "w");
% v7 F; I ^/ Y- G6 C - if (fp == NULL) " a' M" \8 a9 i# h$ s
- {
/ F* _% r% D7 i+ D' C) n& x4 K - printf("File:\t%s Can Not Open To Write!\n", file_name); : q, Z+ d h; [" L3 F
- exit(1);
- ]. D1 q8 n6 j9 T' W6 K - } : `) H5 \/ W. D% r
. V" H" ^# F$ V4 j9 k- // 从服务器端接收数据到buffer中
6 p! Y( L9 i8 U - bzero(buffer, sizeof(buffer));
2 d- H7 N8 m4 c4 q6 A- d' X. g - int length = 0; 8 }# Z: c2 ?8 i/ }/ \0 r
- while(length = recv(client_socket, buffer, BUFFER_SIZE, 0)) + p2 l. a1 _4 o S# P5 M* S
- { ' r2 A6 Q/ k0 k' q J2 h
- if (length < 0)
8 _7 c$ v9 Z8 j( u. v - { - f) S6 V* H: }- V3 ^$ c2 w
- printf("Recieve Data From Server %s Failed!\n", argv[1]);
4 P. V, B. H( G5 _+ F9 m% j0 Q" | - break; ( f3 J5 m0 i* r; n. J r
- }
! X, W" ?7 x+ w. X4 S7 w - 1 T; j" x) @* y3 W9 E
- int write_length = fwrite(buffer, sizeof(char), length, fp);
2 ]3 _- F% n' [$ w8 k$ S' q9 H - if (write_length < length) - R& [% f6 ?$ y
- {
- E5 M9 y# F1 h/ ?& ] - printf("File:\t%s Write Failed!\n", file_name);
' W! V1 `3 S" }* ]. C% |: o - break;
! k8 m, d- k7 L - }
" Y+ H; z7 \2 u5 M - bzero(buffer, BUFFER_SIZE); / T4 S( q% V+ s- H6 s& ~2 r
- } - B6 z& `! I0 r7 O& R, }
3 I6 ^! b5 S: p& I- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]);
7 G" U% I; x5 ? F, B
! [1 j% l. R! Q, H- // 传输完毕,关闭socket
" o( X; N! V* _ - fclose(fp);
7 y% n: E; b' E0 |4 {8 |! h4 q - close(client_socket);
7 Q0 d4 B5 Z! V - return 0; ) o+ _2 q( `: a0 G% n$ ]
- 4 @- n9 Q5 }. @4 H. R
- } 4 c$ x: V4 o+ h- Z
: L1 B* h4 l9 V! k3 J
复制代码- /*server.c*/, F2 y0 S1 w, v% x6 O. q
- #include<netinet/in.h>: _* a, N; `: C, n
- #include<sys/types.h>
9 V0 \/ _- D1 w' @% j O8 o# q! ^4 ` - #include<sys/socket.h>
1 r9 V/ ]5 `8 @4 S6 d - #include<stdio.h>
- _4 k+ k- D( D; L1 t - #include<stdlib.h>
$ S; D6 f( ]' T - #include<string.h>
. X! U2 ^ ~& c - - M T1 c- e$ I' H9 A9 k
- #define HELLO_WORLD_SERVER_PORT 6666 //端口号 Z1 ~4 y$ P3 y! m8 R5 E
- #define LENGTH_OF_LISTEN_QUEUE 20
3 q& m7 I( o! m+ D( W7 t; U - #define BUFFER_SIZE 1024
" F& g9 x [4 ~1 X& a - #define FILE_NAME_MAX_SIZE 512
% h2 H8 \, r) t+ p( x% y7 N
2 U, j" D- C7 D' {# z. s- H T- int main(int argc, char **argv)& N/ c) j) h `$ ?; Y
- {7 A2 O' O3 J, b( e
- // set socket's address information) p" r" T- C0 @, D7 x
- // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口& O" j9 T3 j8 t9 z6 Q
- struct sockaddr_in server_addr;4 L/ ]% l( V% A; o; X
- bzero(&server_addr, sizeof(server_addr));
) X; l- J3 g3 t6 Y7 x, q0 I - server_addr.sin_family = AF_INET;
6 N" ^' s' C: f& s! s1 ^ - server_addr.sin_addr.s_addr = htons(INADDR_ANY);$ l, A# T& f( K) f( \# ?8 l
- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);$ Q) W3 p0 y7 ?) Q, t4 Z* R
- 1 ]* ?. J: H8 {6 ]
- // create a stream socket, A. u% y: ^' }+ P
- // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口' V6 g9 z6 H% g: s
- int server_socket = socket(PF_INET, SOCK_STREAM, 0);
$ z$ R# |5 v; k/ ^ - if (server_socket < 0)# J0 v$ E$ {. J# B: l
- {# Z( o) V8 n8 n7 j
- printf("Create Socket Failed!\n");
+ E7 d# R7 L$ q3 B/ { - exit(1);/ u C1 l' n" k
- }
/ `) W7 J( N- j2 J! h H0 @% P% g - 1 H7 X: |: A5 j5 i
- // 把socket和socket地址结构绑定9 ?" j! r# o4 h% `5 s% H M8 e
- if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))
% B1 J: l. T9 Z( O& W% u- P& K - {; p# p8 V* w Q" P
- printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);
! C/ p$ T z; t; }+ K - exit(1);
0 d* D( }& ?8 z: s3 E4 C( i - }
! @! Q+ D5 x. V
6 I: d! D7 R7 i y- z- // server_socket用于监听0 Q; E# p, g/ N% k* t2 I/ l; N2 o
- if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))( z5 c. m7 n, b2 n: Q0 M# O
- {
+ [# A( H- ]& I8 G/ ? - printf("Server Listen Failed!\n");
+ ?( }. n! g0 o$ L4 N - exit(1); e% G& `5 p( h0 j2 E: s
- }0 N1 R2 o \( A, ]) z
- ! m! k: W; x. P& c
- // 服务器端一直运行用以持续为客户端提供服务
% ]# P- m$ X3 | - while(1)+ F5 J1 j4 `! \& V8 R
- {! N; E' T3 i3 A* w
- // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept
2 }7 a" r4 [# @" r2 U - // 接受此请求,同时将client端的地址和端口等信息写入client_addr中
# i7 r0 E; \# {( f( M5 U - struct sockaddr_in client_addr;! c4 z) n- K7 T+ @5 o
- socklen_t length = sizeof(client_addr);9 m" E, E7 N/ H2 `
- 2 y; a: s& K# [+ A$ Q B" w
- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中4 B) X0 y) @+ Z T
- // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以
$ @# B* [+ ^# i - // 用select()来实现超时检测
' v6 i$ T2 D% X8 f( \. b3 g2 E( ^ - // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信. K5 ~( a0 V/ k: B
- // 这里的new_server_socket代表了这个通信通道
# }& ]4 ^/ ?1 O; p; q u% s; t - int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);
# l0 z% n3 ]/ i - if (new_server_socket < 0). t6 E+ b; H3 X: R1 _. M* o) U8 \3 u0 f$ f
- {
4 D) u* {& ]: o% Z6 x - printf("Server Accept Failed!\n");
$ d# x( G- X4 V5 l- p0 g% Y# x! n - break;
4 x" x3 y! A: e9 @5 Z6 G. N - }+ q( E. K& N" g% O
- 8 X, L9 I( `: x6 S) r
- char buffer[BUFFER_SIZE];, C% k l" q( m G4 [ x% O7 t4 b2 Z
- bzero(buffer, sizeof(buffer));9 P& ?. r. g5 Y
- length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);
/ D& S% Y/ Q, y J: u l9 A - if (length < 0)
: ?3 A2 F: f1 @8 N1 j1 e4 P - {
1 ]+ W# e/ ?' s2 _9 y, c - printf("Server Recieve Data Failed!\n");
$ @. b/ J: O( H" ?. c! d( e; Y+ a+ x - break;! E' U7 d1 ~* K7 |1 w
- }7 C7 n1 C% }* l8 {/ }9 F
+ x3 N, e/ H* j% K. L- char file_name[FILE_NAME_MAX_SIZE + 1];
7 H" `: o: d! ^1 ?) [/ D5 W - bzero(file_name, sizeof(file_name));
7 @' f1 I8 ?8 I& E5 n' F - strncpy(file_name, buffer,
* Q1 ~/ k/ P8 u: O% J; ^1 } - strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));
- h6 B5 a& L6 {0 m - . e" z+ H4 s5 r5 A2 }- z8 j
- FILE *fp = fopen(file_name, "r");0 M/ d8 j J v$ j8 w8 d+ b. S& O) t
- if (fp == NULL)
# h N! w7 o+ g# f - {8 z0 t$ X: ]' S$ _1 o* C D
- printf("File:\t%s Not Found!\n", file_name);
9 Y" y- ~0 O( A; _' h y( t - }
x3 l' j1 |- y* g - else
! O: `! \0 c& G) b! W" O - {- o, c4 K/ }$ ^2 e V) m
- bzero(buffer, BUFFER_SIZE);
- B& @$ S! t9 m8 d! \& A - int file_block_length = 0;' A7 _6 p" ]6 B; B- x- K
- while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)5 g B% ]; d" r0 L
- {/ ]! j" x/ {4 N3 |
- printf("file_block_length = %d\n", file_block_length);. {$ k: g& s/ _: r+ \
; ~. w3 ?' K& ]# V2 H; x# [- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端/ U% ?& c" h3 {# x
- if (send(new_server_socket, buffer, file_block_length, 0) < 0)
; N1 z A8 z1 q0 @4 g2 b* C - {
% E4 M7 }% G1 `+ q - printf("Send File:\t%s Failed!\n", file_name);
, W" V. B5 b, C0 S5 X - break;
& u3 L5 Y; u9 @% u& ^4 E- ] - }/ x0 m3 y9 \; o1 O/ Y0 N- d
- * V' M6 [! A* z- k
- bzero(buffer, sizeof(buffer));0 I$ ?8 B3 J, i1 \, D$ J5 V* {2 d
- }0 G5 ?) b* A3 P3 y2 e
- fclose(fp);8 Y8 U: W( L9 e/ ? o6 r) x6 P
- printf("File:\t%s Transfer Finished!\n", file_name);6 Q0 _- X; J4 w
- }1 w+ e M5 \, W0 Q; x. h
6 u+ u; K# I# z; v- close(new_server_socket);0 ~- r1 S1 X5 a3 l6 j# G% d
- }) ^. h1 t) o+ d
- 9 o+ Z/ A/ {( q/ z: q0 Y4 T
- close(server_socket);
+ B+ l0 c% j4 P8 w) z* @ - 5 W7 k8 J4 q# l$ s. C% a1 A
- return 0;
% K4 g; l+ Q, n - }6 `* T) ]& |' X, ]5 L
- 7 Q4 V5 A. e+ c5 Q: L
复制代码
! l' K5 T4 C% l) H5 f
8 @$ Q5 P& k- J+ U+ g9 G( j, Y% u1 t* A
- _, d3 N" `- ]- t |
|