cncml手绘网
标题: 一个很实用的服务端和客户端进行TCP通信的实例 [打印本页]
作者: admin 时间: 2020-5-9 01:46
标题: 一个很实用的服务端和客户端进行TCP通信的实例
本文给出一个很实用的服务端和客户端进行TCP通信的小例子。具体实现上非常简单,只是平时编写类似程序,具体步骤经常忘记,还要总是查,暂且将其记下来,方便以后参考。
. D6 Y+ F( N! s& @, q(1)客户端程序,编写一个文件client.c,内容如下:
! A3 ~3 f4 M) J- B" m9 A3 B- #include <stdlib.h>$ G! Q0 b* p6 n3 t' I4 |, v z% N2 _
- #include <stdio.h>% I# u: o) Q$ ~' X3 O0 r
- #include <unistd.h>
4 e4 R0 F' `1 H) p9 z - #include <string.h>$ g/ e2 ]8 ^! j P1 m* a
- #include <sys/types.h>+ `2 x1 p O$ Q* ^0 x# F
- #include <sys/socket.h>
8 h* J# h# n, ^1 s! [( \& b& a# K - #include <netinet/in.h>3 m; ?: a |4 I7 c8 c
- #include <netdb.h> /* netdb is necessary for struct hostent */
, C; u, s) h X - 2 c5 W) [3 _2 e6 C# Z4 {
- #define PORT 4321 /* server port */0 h- [" T, l1 @' [4 [
9 ] U2 d3 F, X- #define MAXDATASIZE 100, b4 v, M% I& x& T; o! i
9 `5 J0 z( W, d7 E- int main(int argc, char *argv[])
- N; \, V, p' l( K: T& J - {
' K: ^6 X0 ]* r- O# ^, F3 _% [ - int sockfd, num; /* files descriptors */% b9 c f5 }* P1 }
- char buf[MAXDATASIZE]; /* buf will store received text */
# M. [- ?( M; ?2 I' j' S - struct hostent *he; /* structure that will get information about remote host */
2 h8 |9 p6 F8 u; s& j - struct sockaddr_in server;
; w; }! \/ a( W, l& z$ V* { - ) z. T7 Q0 J: k
- if (argc != 2). l2 P/ E6 i! u6 L
- {
9 y2 | _- n( c/ h# [! X! ? - printf("Usage: %s <IP Address>\n",argv[0]);
: T7 C2 w' w0 }; u; l9 D - exit(1);
1 g: T0 c' t( D - }
$ [9 D A7 _, M3 K+ i" ~$ \ - * _( {* R9 H( k; b M, P
- if((he=gethostbyname(argv[1]))==NULL)! z# L( a( l! R! }: N: D
- {/ ^- F7 f) ^) F: H) W" H
- printf("gethostbyname() error\n");
; k6 | U3 ^6 J8 ^ - exit(1);
8 I/ \, k; B9 T& W, L6 b8 i - }
* u8 |3 h2 Q9 k) K5 b3 R Q -
/ W3 X" b: O9 p - if((sockfd=socket(AF_INET,SOCK_STREAM, 0))==-1); n* o+ q& [& {6 N+ d: q' ]
- {
- C! M3 ^9 [! }+ }/ i - printf("socket() error\n");! O6 c$ Q6 W6 s4 g
- exit(1);& Y1 W) \" D1 n U- y4 ]% c
- }9 d& y/ t% M- n6 n% d7 l
- bzero(&server,sizeof(server));
3 x4 `& t( m- i - server.sin_family = AF_INET;
: x6 P$ D2 Z/ ~. r$ q* y - server.sin_port = htons(PORT);
. x) |) Y2 p! u W4 E8 Z" b5 E - server.sin_addr = *((struct in_addr *)he->h_addr);
" T2 B8 ~ j2 B9 B X% F& D: Y - if(connect(sockfd, (struct sockaddr *)&server, sizeof(server))==-1)
; M' @& P/ m8 n! F+ q: W' U0 C" } - {
& c, Q' _5 x# i9 V - printf("connect() error\n");
- I9 | f+ O. i4 b* f3 n - exit(1);
+ s7 Z8 J7 Q8 W$ k( D+ i) @& _9 w - }, X: Q4 d* G8 A5 ?8 L! e
- . k2 Y+ ~) X3 }
- char str[] = "horst\n"5 E1 c( C/ N" s3 C5 p
- 9 |- y/ B' Y( u' [9 ~$ r& @5 ]
- if((num=send(sockfd,str,sizeof(str),0))==-1){
- I4 E% P- v9 i/ L - printf("send() error\n"); ^7 D) G( u% A5 q
- exit(1);: N2 [- y3 g5 J# f1 Q5 X
- }
" h: V+ c/ B8 ~% V! {; f* w - if((num=recv(sockfd,buf,MAXDATASIZE,0))==-1)
' G- A% B; s/ d; d/ K% d, ]1 O - {
/ V k; q! ]( G) v; l - printf("recv() error\n");
S/ ~3 i- _3 \ - exit(1);
u$ J$ w( V, m% A7 o* f9 z - }
( [+ o" c' H8 e) V# y. Q - buf[num-1]='\0';3 t% N& Z- h7 ]6 c6 D
- printf("server message: %s\n",buf);. s) O8 v" N, V8 \6 [! {* V
- close(sockfd);
* O; P* v, \" e3 j1 @ - return 0;8 R* L5 `- W8 Q8 e7 Q( y
- }
复制代码 (2)服务器端,编写server.c,内容如下
5 ]. b4 d8 [5 h+ S$ L- I, g- #include <sys/time.h>
& j! v! v' f4 w1 ~4 ]+ I - #include <stdlib.h>3 w; Q/ k/ p! Z+ d6 L/ ?1 G
- #include <stdio.h>0 V' F* G3 q5 q+ \! W
- #include <string.h>
4 z' X" e7 r% C' }; o - #include <unistd.h>4 w& m; f* N. I3 K* m' M
- #include <sys/types.h>
- p, @' V. G4 B- \) t - #include <sys/socket.h>8 L0 H. T0 g8 v z; Q
- #include <netinet/in.h>
9 G+ Q5 W% k+ R" W0 V" l - #include <arpa/inet.h>
$ A& F, Q A' d0 O - , D! U; ^, y/ w$ ~ I1 {& J5 ^. X2 p7 g
- #define PORT 4321& f+ r- F& y" J1 M
# V: k( ]; H; F- #define BACKLOG 1
+ @; J& E2 _0 k8 H W+ d+ t& o - #define MAXRECVLEN 1024; U& O9 }4 f( ]4 f6 H0 H. Q o& S, ?
- # o4 V1 [2 a6 K
- int main(int argc, char *argv[])
# u% D3 b8 R' Y& f+ h O% D1 @ - {) u+ D0 B) F7 \
- char buf[MAXRECVLEN];( {. K9 K. |: p: G/ \( ^' Y
- int listenfd, connectfd; /* socket descriptors */: ]1 |3 o* [' m0 a1 {. m3 C8 j
- struct sockaddr_in server; /* server's address information */# o+ m* d/ o' ]
- struct sockaddr_in client; /* client's address information */
" o) V$ T' W1 g - socklen_t addrlen;
0 _+ `* y! j I& b - /* Create TCP socket */
' ^5 R2 @0 I0 z& h% B$ u- k2 R - if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)& D& z" |! }) G0 ~
- {
' E" d" I# ^" p6 U8 j0 U* M - /* handle exception */
( X) ^. v8 y& t( d- m5 f0 _% p - perror("socket() error. Failed to initiate a socket");
/ v! Z- q, M& f5 k# X& T4 o - exit(1); P) G$ m; @9 t, y* L7 W6 c2 o7 B
- }. F2 O0 U0 n1 P- l
- . i6 K3 T! {8 X$ e9 C V. {# b
- /* set socket option */, x2 L1 ?+ z, K5 h8 c9 O( J
- int opt = SO_REUSEADDR;% R) c: E! w/ B) O7 v4 }& i7 L5 u8 u
- setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
: b& ^" K G" r6 {
5 T% Z& ?( K' O& i; v" w% a8 p- bzero(&server, sizeof(server));
) w- i" s# @ H# J) y' F! g - + V5 ]! T0 D: z) b5 `
- server.sin_family = AF_INET;& z3 E$ F. B* Y
- server.sin_port = htons(PORT);+ y k4 e6 s; W7 x7 G
- server.sin_addr.s_addr = htonl(INADDR_ANY);) r5 l f( p1 @( L ?6 W
- if(bind(listenfd, (struct sockaddr *)&server, sizeof(server)) == -1) g5 w. T$ Q, H% x+ T
- {
0 X0 Y' E d T% f9 j9 [ - /* handle exception */+ ^ c0 E+ n0 L" H
- perror("Bind() error.");: z4 h' C: A* ~# I2 Q
- exit(1); b) A3 i- M3 [, t6 m% U, N+ |9 S" m
- }! [4 p' j: ]! o e
-
6 _9 n# K' x) f$ \8 ?% w - if(listen(listenfd, BACKLOG) == -1)
u' H2 K# p8 H - {2 j4 r5 Y$ X4 d/ N, Z" s
- perror("listen() error. \n");: u: J* l; J& p2 W Y7 d% _
- exit(1);3 f5 a$ D' k& N. U, x
- }/ Y* y; k- R& |( K9 ~8 B7 i
3 a% k8 _9 P% x9 H2 n- addrlen = sizeof(client);/ b: \! |# d/ r3 l8 S' S
- while(1){
; d1 i: p& {2 @$ u9 | - if((connectfd=accept(listenfd,(struct sockaddr *)&client, &addrlen))==-1)
0 n t; v; ~1 a% Y5 n% R - {
' G6 C, r8 g: ?* W& f7 W) t - perror("accept() error. \n");
) X; b! @1 s) ~ - exit(1);
& W* }7 |' {. m+ Q - }: ?* B! g& K3 \, u* I
. j5 `3 v) Z* U, v8 o8 E- struct timeval tv;# V) m; `: j$ ~6 i
- gettimeofday(&tv, NULL);3 ?+ H7 V' B8 F1 v
- printf("You got a connection from client's ip %s, port %d at time %ld.%ld\n",inet_ntoa(client.sin_addr),htons(client.sin_port), tv.tv_sec,tv.tv_usec);' N7 e* b! z% |) e8 G- ?2 t
-
/ X2 }+ E0 Q; E* j' q6 g- e q X: C - int iret=-1; r% |# i: z, b! ~7 g) }8 K: S+ {
- while(1)+ q [6 {7 e0 }% F$ H I1 z
- { J) R& e+ u; ?* Q4 o1 z2 J( g
- iret = recv(connectfd, buf, MAXRECVLEN, 0);4 Q; x5 ?- d. S& s0 r
- if(iret>0)9 E, U4 f7 k- g6 @( T6 L, f
- {
3 ~1 H4 i0 L) t% |& ?# k* P - printf("%s\n", buf);$ L' T1 I3 y7 `
- }else
6 n2 s, S" ?3 B8 i" B - {
7 q5 f; [8 o# s7 o - close(connectfd);
. @& s: L1 O! }1 z" C& D3 D, ~ - break;
. q/ T- y( P4 n! h4 a# ^ - }! g4 p. [9 i- `
- /* print client's ip and port */ P5 w& L: g" @. \
- send(connectfd, buf, iret, 0); /* send to the client welcome message */8 f8 G/ z1 Y6 |0 c. o1 A5 U
- }0 z: m! _, d. m0 S2 S, H
- }' o2 q2 e; A; W. e
- close(listenfd); /* close listenfd */3 `/ c; U/ q0 c' Z) I% l
- return 0;3 p/ B; ~" _9 T8 F/ s0 K
- }
复制代码
6 `; T# y0 X2 R- G
$ B( [4 K/ G5 V$ E0 ](3)编译运行
以上两个程序放在同一个目录下,比如 /home/horstxu/Cprog/tcpCSmodel
命令行进入该目录 $ cd /home/horstxu/Cprog/tcpCSmodel
命令行执行 $ gcc -o client client.c ,可以编译出客户端程序。
命令行执行 $ gcc -o server server.c,可以编译出服务端程序。
命令行执行 $ ./server,启动server程序。
这时你可能需要重新打开一个命令行窗口,到刚才的目录下,执行 $ ./client 127.0.0.1,启动客户端程序,就可以看到结果了。
客户端:
- $ ./client 127.0.0.1
6 z6 R$ L3 `5 A% |5 A
1 A% }3 m+ l& d9 ~- server message:horst
复制代码 / U( K$ B8 m$ I1 R: ]( F; ^; _
服务器端:
- $./server2 ^; t; w7 P* H8 L% d9 Q% S7 j) V
- you got a connection from client`s ip 127.0.0.1, port 60865 at time 1418281267.643428
复制代码本程序客户端会自动退出,服务器不会,因此如果想停掉服务器程序,直接在命令行界面按键盘Ctrl+C停止。
程序实现的功能很简单,就是服务器监听4321端口,客户端与之建立TCP连接后,再发送字符串“horst\n”到服务端,服务端打印出来,然后再把字符串传回给客户端,客户端再打印出来。然后客户端关闭连接退出,而服务端继续监听4321端口等待下一次连接。
/ I9 U9 t6 ]) K; R! v- r; _
9 Q6 v2 W/ ]2 p Z4 V" K1 Z2 I& q& M8 i
. { C1 n% z2 s/ Q0 `
作者: admin 时间: 2020-5-9 01:48
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段.5 c# ~3 x# y4 g0 P D6 O y% y$ O
- /*client.c*/
( k9 }8 u. x$ t) P' I& J% g - #include<netinet/in.h> // for sockaddr_in 4 M6 K2 t0 v( g) u8 c+ w% U) e
- #include<sys/types.h> // for socket / G: ~% K/ C; B
- #include<sys/socket.h> // for socket - h7 l6 M/ A, H5 u; X, v$ s
- #include<stdio.h> // for printf / t B# r: [% S
- #include<stdlib.h> // for exit 7 [% E+ K+ t- ^2 D" h9 m
- #include<string.h> // for bzero
% j( [, }* `0 @0 J, }5 b; E3 X% Z - 1 B2 V7 L2 S a8 u3 ]" F( N
- #define HELLO_WORLD_SERVER_PORT 6666
# }& [7 i# T2 h5 W3 _ - #define BUFFER_SIZE 1024
. m7 U& O5 m P - #define FILE_NAME_MAX_SIZE 512 ) H5 d2 d& t5 l9 t1 Q
; C0 q/ S' G9 O) J- int main(int argc, char **argv)
, L' v5 Y$ b; _5 R - { 2 t8 e, E `( M! r) p+ g) V
- if (argc != 2)
2 x7 V8 H5 a0 d) F9 A+ m9 U - {
5 u; W/ l# Y7 @ - printf("Usage: ./%s ServerIPAddress\n", argv[0]); ' b' F) Z5 r. R7 o+ @; T
- exit(1);
& X0 h* T# i/ {1 z5 B; n - }
; I5 Q. }3 t( @1 [
+ q6 q% @. A3 K" o8 k% Z" L- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口 7 {, _, k( `* g0 D* h3 _. R- r
- struct sockaddr_in client_addr;
5 v- Z% |6 E, T5 K/ f - bzero(&client_addr, sizeof(client_addr)); 5 A8 d: K- Y& Q# d
- client_addr.sin_family = AF_INET; // internet协议族 9 B" T; W* }; I$ `5 c# h. Y# w/ `4 _
- client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址
; P: n# _9 y3 n% A7 O% B8 M3 P - client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口 8 I9 V$ _( N+ {7 V5 C' f
: k( p+ p B/ Q+ F$ q- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket
: G% c2 |! S2 K+ H$ J - int client_socket = socket(AF_INET, SOCK_STREAM, 0);
; ^# `* V/ j' }- U, [1 V: a& j - if (client_socket < 0) 6 B) F. N# _, p8 q7 p! J5 q
- { 7 a* _" ?3 R$ P" \
- printf("Create Socket Failed!\n");
O0 f8 v# P0 s, K - exit(1);
: I/ H, s! j* N Q8 o4 R4 X8 L - }
2 U3 {$ K p0 n: [1 ?0 Y
5 K% V+ h; T+ P+ N$ S1 D- // 把客户端的socket和客户端的socket地址结构绑定 ' @6 v0 o8 z& D1 X: Z: `
- if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr)))
3 E; e7 m5 J, K - { ' C, N! L) Q- g
- printf("Client Bind Port Failed!\n"); ) S3 z. G9 `$ E# p$ g; b
- exit(1); 0 P9 y, V$ Q6 w8 @; S* e. Z
- } 5 y3 ]& v, L3 \- I$ r( w7 ]* U
" M; q( r# S* Z' Q7 x- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口 6 ^" y. z) A" j0 I. {$ p" B! t7 _
- struct sockaddr_in server_addr;
Q( s7 i# o# u - bzero(&server_addr, sizeof(server_addr));
' [, t3 W* l( a( Z0 l - server_addr.sin_family = AF_INET; : f8 _2 _5 f! t6 b e5 u6 v
- V7 i! @/ _, b& z0 L- // 服务器的IP地址来自程序的参数 / X0 V: w& t* U& y, V( _2 T& m
- if (inet_aton(argv[1], &server_addr.sin_addr) == 0)
. ?6 s# O6 r) R- c - { # W: w- s) ~* J& d# o5 |" N
- printf("Server IP Address Error!\n");
1 T- Z! V2 D6 i8 ^* l! @) V5 a - exit(1);
) ]/ a& D, S% h: j2 J$ t5 L$ | - }
0 H8 g' P! `+ T" j - ; N+ R4 q9 B- ?& g% x6 F; n) W( ^- K
- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT); / |( I; d, |" y& Y: P
- socklen_t server_addr_length = sizeof(server_addr); ! U, J0 E+ B# g, v& b) j
% w, X# W& R! v- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接
4 _. s5 @$ _$ L- R( P0 M6 W - if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0)
7 ^! O& \" W0 k2 H n: k( u' Q' @9 i - {
# s7 ~) c( U" p% Z - printf("Can Not Connect To %s!\n", argv[1]);
; h# [' q6 o4 w( k0 e3 E6 v - exit(1);
$ h0 C& O( Y" n" Y1 I% F3 J - } ( Z% _2 k7 [ \1 \: g" C2 U! x, E
- + X7 I/ v6 S/ ^) U- x. ]9 U
- char file_name[FILE_NAME_MAX_SIZE + 1];
6 m7 l: e$ v4 q6 r3 x% @" e - bzero(file_name, sizeof(file_name));
: A; T" H7 |- n ~, k0 r0 P - printf("Please Input File Name On Server.\t"); 6 N# J& ^: A; K3 E' K. a& w
- scanf("%s", file_name); . u! r4 X# Y2 L1 k. ?
- ; ~: x# N, S9 Y K) k: M
- char buffer[BUFFER_SIZE]; # J3 w U2 Z8 w+ k
- bzero(buffer, sizeof(buffer)); $ s$ \" X t, T+ J/ \7 X
- strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name)); ( C, t! b$ l2 n/ x& J
- // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字 5 ?3 c, ^ i; Y# U
- send(client_socket, buffer, BUFFER_SIZE, 0);
4 B2 {* ~& b9 D: G2 R - ) G, N Z9 u' J$ k
- FILE *fp = fopen(file_name, "w"); % ?: T. `/ u9 n
- if (fp == NULL) q Z+ F, _2 P$ ~! r& E# `
- { . a5 }( u' d' g) ~7 }0 {6 w
- printf("File:\t%s Can Not Open To Write!\n", file_name);
+ G$ H% g3 x5 h( u+ m1 G: d - exit(1);
) J' v5 i- Z5 F' F5 R6 G; g - } $ l' Z4 o W% a) r
" ]1 {# ]% L+ X: \ X) a- // 从服务器端接收数据到buffer中
, ^, `5 E0 d" N0 w, |) X - bzero(buffer, sizeof(buffer));
: X) [( m$ G* D) A: x - int length = 0;
* Y3 x; p, I2 t. h+ E$ \4 | - while(length = recv(client_socket, buffer, BUFFER_SIZE, 0)) ! t% S) e7 K( \# X9 B9 I* \
- { ! r$ i& Z* K- z7 j6 [1 A9 w/ X
- if (length < 0)
7 N4 `5 ^4 ]9 N! O1 C6 t - { L* I. C8 a8 X ?/ D
- printf("Recieve Data From Server %s Failed!\n", argv[1]);
% d, ^" Z$ m: Y0 E* @ - break; * N" J E) ~/ I) w) k7 X
- } ; u7 X6 E6 D3 v
- 0 T' I% D7 w/ j$ r6 U
- int write_length = fwrite(buffer, sizeof(char), length, fp); 9 @: `$ \( o+ E9 D9 p
- if (write_length < length)
, W" S2 z0 J- }% U* } - {
- r5 d& S; C; _, `& Z - printf("File:\t%s Write Failed!\n", file_name);
Y8 r$ V4 l5 _2 N! w* g- S - break;
" p% A4 z% k8 _4 I; \7 J- E. g - } ! E$ n- g7 {+ f
- bzero(buffer, BUFFER_SIZE);
5 T' X5 Y% D9 ^6 V( t8 [ - }
. f" j. C2 s, [& t) Z" e/ e - % T$ q, J& |, Y4 p
- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]);
1 H' w* C1 h. T
) F$ U: B s! J- // 传输完毕,关闭socket 3 p- R: S+ T) P% b: Y. M) @4 ]
- fclose(fp);
; `# @- f/ H( i7 ]6 N- I' m, O - close(client_socket); 1 {' F4 v) I1 }+ S2 z* z
- return 0; 6 D9 K8 M. D6 \! P
+ f$ X' x/ p& g, `8 n1 O' u" ^: Z- }
+ M; p1 \! W* c* f/ b
; H$ W/ I% [) i/ a# S3 a( X
复制代码- /*server.c*/
$ X4 I" h8 T: B/ k% S - #include<netinet/in.h>9 s; [9 S9 m/ E
- #include<sys/types.h>; f" u0 T. m$ k% X% C4 u
- #include<sys/socket.h>2 j5 y% W2 H% o4 a! N# z o
- #include<stdio.h>. R" D4 ?; Z' B/ B; R) f
- #include<stdlib.h>
9 |- ^" @6 [7 ]. W; R) f$ }" x/ n( H - #include<string.h>. i, E2 J6 E! {" C' L: ?: J
) F% j: O# e) }0 h: I" |5 ?2 j- #define HELLO_WORLD_SERVER_PORT 6666 //端口号4 @ q M8 T; S/ ` A* ?
- #define LENGTH_OF_LISTEN_QUEUE 20
, X5 c- F$ u5 M& L$ f8 X- a1 H - #define BUFFER_SIZE 1024' @! T4 T! Q. m+ @* @
- #define FILE_NAME_MAX_SIZE 512: P3 r. W1 c! C) X/ a- c) X
( d, V- C9 T! D, l$ F- int main(int argc, char **argv)
$ t: w+ }) G1 z5 E$ [# s/ n - {
' V$ n, j. r3 Q0 f - // set socket's address information
% ]* [5 F" R5 c" \, U - // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口
- s. ^8 y3 V! A - struct sockaddr_in server_addr;
. Z6 _" C H2 D [ - bzero(&server_addr, sizeof(server_addr));7 S( g# t6 G0 ~( W1 Z* A- _) [1 m
- server_addr.sin_family = AF_INET;$ i9 a( N! H+ w
- server_addr.sin_addr.s_addr = htons(INADDR_ANY);
# |1 D4 ]1 _5 b- b: v+ A) p% h* B* S - server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
2 n N' M7 G2 Z# R
6 k5 m# Y& P4 S: y2 v# Y: R- // create a stream socket
4 X1 B- h2 r* T! Y2 P - // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口
4 n: v) w: f# r9 g9 l - int server_socket = socket(PF_INET, SOCK_STREAM, 0);0 u; Y9 G# X* H! U
- if (server_socket < 0)4 U: z& q9 V$ N1 G. ~. Z8 r
- {9 n8 S: g' j& M; y1 m! Y# J. x: B
- printf("Create Socket Failed!\n");
! f# n: q/ |; t - exit(1);( x0 V0 A0 {- {0 R+ w* D9 q5 Y
- }: A7 W; [- ~. a8 F4 W7 s
. l9 s1 @7 f( ~$ L% T- // 把socket和socket地址结构绑定
6 F9 J8 Y# A- ?, z1 e! u% P. Y - if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))
, V/ c$ J5 j2 f! u - {4 s/ [0 v* y; i/ ^: H
- printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);
. M; ]4 n, v$ r4 B, ` - exit(1);
7 F; K5 ?. K/ r4 \0 I1 A2 M5 Y - }5 E$ h. b0 I' l5 u O
- & o9 v% V( d1 \# o# S9 u3 B- }
- // server_socket用于监听
' \ h+ v F3 {& r7 Z/ Y( f8 _. H - if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE)); O' Q1 ?9 k* f, s7 a2 s+ u* S& z
- {9 y S5 o* K7 L# S* U: x
- printf("Server Listen Failed!\n");
2 }+ v; o- Z# a* o - exit(1);' Q) x' J2 B3 u
- }
5 C6 c( }" i8 L5 q - 8 k9 J* S! W& a w: T* N1 G
- // 服务器端一直运行用以持续为客户端提供服务3 ]8 a) M' i+ e- q
- while(1)
8 Z7 Y9 I) j' N! D; H: Q3 t3 x+ b - {+ k) y- u; [7 B5 n8 W: Q& W
- // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept! l) @* }+ q1 O
- // 接受此请求,同时将client端的地址和端口等信息写入client_addr中
% U" _0 D9 H# Z: M$ y6 w# V - struct sockaddr_in client_addr;. p/ ]. m6 Y3 J+ u& {
- socklen_t length = sizeof(client_addr);* R/ w0 W/ B5 ^1 d7 {" N
- ) x4 y' ]. l% O4 l
- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中
( h4 R G% n/ M( T- `& r - // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以
: B" L" Q% Z; @/ k" S2 m% w4 g - // 用select()来实现超时检测* k) @: W m$ V
- // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信
5 J. W4 A, C0 M% X* j9 ]) g# y' }' n - // 这里的new_server_socket代表了这个通信通道
7 U; u; \7 x1 p. a - int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);
6 f Z/ P1 A/ A5 d% z ]* c - if (new_server_socket < 0)7 x2 H5 P* q+ w
- {
3 F. }2 Z8 h" ], \0 W" ^' k( M - printf("Server Accept Failed!\n");5 }' [& X( x& I! _ k4 a8 {
- break;- A. g$ {/ d' K3 b& A/ q0 J T" x) ^
- }2 @+ L# g |/ c3 a# B, \5 C" c3 P
- . ]9 k4 Q$ ~0 I; r
- char buffer[BUFFER_SIZE];
V' P+ C+ I% X7 X* g+ P - bzero(buffer, sizeof(buffer));9 ?! h, V% U4 z* R4 H6 q
- length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);
6 F+ {: R) o: ]: H - if (length < 0)
' w6 G. x8 {* K* f5 ? - {
5 D2 A! p$ a+ g& h* `8 D; H - printf("Server Recieve Data Failed!\n");% H V* O | B7 _8 v& R. E
- break;
7 O# }/ q5 P& { - }
1 Q- q( p8 o% M! t! g
" G8 [4 e' Z7 N( q9 G- char file_name[FILE_NAME_MAX_SIZE + 1];: v. c3 E% x; P! W
- bzero(file_name, sizeof(file_name));
" x( P/ _# ^; d5 B; y _' y5 e2 v - strncpy(file_name, buffer,6 s- [9 {2 m* |) I3 t+ ?! _: f x
- strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));# D0 N1 [0 y2 s! ~, q1 M
- # A) p+ q& Z0 r
- FILE *fp = fopen(file_name, "r");% d) C1 ?& Z6 K' ^/ ]
- if (fp == NULL)* Y2 U1 f3 i9 z) O2 o$ _+ L
- {4 I* m, N2 {5 e- D( R- l% S) o
- printf("File:\t%s Not Found!\n", file_name);
' a+ X! Y" }8 K8 z. k. o - } H% b' f ?$ v5 a' V* R
- else1 _* c8 E; t8 F% F# y3 t! I
- {
! W/ R( y* Y( b) _7 q3 s - bzero(buffer, BUFFER_SIZE);
7 B( M& }* Z$ r6 G* S - int file_block_length = 0;
$ s: O9 N# s1 {+ ~0 }9 L - while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)' k* }: ~) z4 S5 W, @- K
- {% a$ X5 h0 U3 p8 T
- printf("file_block_length = %d\n", file_block_length);0 y6 l4 X. p6 v5 f1 b. M# F- M4 Z0 I
- 1 Q- L1 v& p0 f9 \
- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端
+ H5 X$ F9 t9 S6 J# z* G, T - if (send(new_server_socket, buffer, file_block_length, 0) < 0)
0 \4 K& a, a, q# N& E! C4 ~- d - {) v% S/ E+ x ]8 L P; X
- printf("Send File:\t%s Failed!\n", file_name);
- D" ~5 m' q. v1 R2 ?8 _ P1 Z - break;
: b7 v. z3 `! Q- `0 e/ A0 G - }+ Q6 o+ e1 H) O1 @. V
( N: ~8 `7 j& ~% _7 Q7 d+ Z- bzero(buffer, sizeof(buffer));
% z4 |: _) h% q0 V7 W' M3 s; q3 @ - }2 R: h/ S7 l4 W# o! U0 V; E9 ~
- fclose(fp);
( ^- u1 W5 b: T% ~& `- c$ y, k - printf("File:\t%s Transfer Finished!\n", file_name);4 Y( _# E. i D4 K4 W( S% J
- }
5 ]: P3 r9 H( `: @
4 E( y4 s( c' p$ B: J3 a+ T- close(new_server_socket);) r$ Z* G; H( P
- }
- g' n( m8 |) ~+ v u
! X1 e8 K4 O& [0 X- close(server_socket);
$ x& ]* V# D& h R1 Q
, @0 S* l+ c) i+ j" X- return 0;
; ]3 O. r4 O2 ]# P" E - }5 F( u2 d- q2 K' S
7 s' `8 H2 ?) q# ], s7 R( O' V+ \
复制代码 9 J# [* |- P7 d
) @$ S% k# l/ F6 @3 g7 ?# G
: T, _8 x1 Z; t% M7 F* v# q. S- `; I
3 k! O3 t7 w% Z* ?
| 欢迎光临 cncml手绘网 (http://www.cncml.com/) |
Powered by Discuz! X3.2 |