cncml手绘网
标题: 一个很实用的服务端和客户端进行TCP通信的实例 [打印本页]
作者: admin 时间: 2020-5-9 01:46
标题: 一个很实用的服务端和客户端进行TCP通信的实例
本文给出一个很实用的服务端和客户端进行TCP通信的小例子。具体实现上非常简单,只是平时编写类似程序,具体步骤经常忘记,还要总是查,暂且将其记下来,方便以后参考。& |; m* n. U7 ^2 J) {0 w
(1)客户端程序,编写一个文件client.c,内容如下:) Q P4 P# J* X" @5 s8 v
- #include <stdlib.h>' O1 F# S+ B' m7 v
- #include <stdio.h>. j' F7 A% t$ @% E+ R
- #include <unistd.h>! H2 C6 U6 s0 ?% r+ V
- #include <string.h>
" N) r, p, H1 u1 Y: n' K - #include <sys/types.h>
$ E- h( W/ l* ]2 t - #include <sys/socket.h>8 Q! a, R" W8 g) @
- #include <netinet/in.h>" W" h* O7 T( l( X k
- #include <netdb.h> /* netdb is necessary for struct hostent */& j& \# x5 @9 f! E' ?) Q h/ s
- i* W/ @' j( `- #define PORT 4321 /* server port */ Y- Y/ j/ R2 P% _. M
6 _- T/ L5 E& p! f- #define MAXDATASIZE 100* Z# V8 g: l3 t! `3 H
- 5 A$ t( x/ f7 r7 V: e- h- n- E: E& [
- int main(int argc, char *argv[])' A+ z% c3 g( N/ i# M7 v0 R
- {' [ j1 s4 W5 p
- int sockfd, num; /* files descriptors */9 Z0 ]4 z; Z$ f) y8 F0 [
- char buf[MAXDATASIZE]; /* buf will store received text */) N) l& L& i+ d0 V/ R
- struct hostent *he; /* structure that will get information about remote host */
1 |" e9 }9 t8 S! [1 o; x' \ - struct sockaddr_in server;, l9 ?+ ]' q$ x4 }( g* `& m4 T% f5 Z
-
" _- F0 o. y2 O# X! l - if (argc != 2)' f& r) x% K& o! c/ s* f+ t1 s
- {! m3 a, U" O! u$ U
- printf("Usage: %s <IP Address>\n",argv[0]);
R" L6 b$ S6 J: x8 r* x - exit(1);5 Q& R& R7 ~$ s; }$ l
- }
% |0 N, E5 X! O3 V - ( r0 `+ y* ]" _* K
- if((he=gethostbyname(argv[1]))==NULL)( C" F8 C; i5 z. c" f% ~9 v/ _% s
- {
+ [% c& \7 @" v. M7 M3 s# \ - printf("gethostbyname() error\n");
" T3 V5 u* p7 ^' N- Q# S - exit(1);5 Z$ C2 o6 A4 T, G7 U4 k, R! ~; L
- }
4 f& J( S5 L: A7 F" ]/ m' x6 _/ z( `/ _6 r -
& W0 t- d% `$ j- e L - if((sockfd=socket(AF_INET,SOCK_STREAM, 0))==-1)
6 J- O" m9 G, J: i/ h+ d7 |* X$ u - {8 M( V5 l& @% ~$ ?5 R* R
- printf("socket() error\n");8 A" ]: ~% p; ?/ s, p
- exit(1);
' s7 @. k! [8 n; t7 ^) D - }
u+ K9 Q0 o+ w8 b5 W - bzero(&server,sizeof(server));0 c- `; V, e: m$ A1 l
- server.sin_family = AF_INET;3 D. `$ ~6 u0 I& ?
- server.sin_port = htons(PORT);" m) g0 B% x0 S8 l& j9 E( [
- server.sin_addr = *((struct in_addr *)he->h_addr);
7 i s% H" [+ a. A6 @ - if(connect(sockfd, (struct sockaddr *)&server, sizeof(server))==-1)( u& a$ q! y" H& r
- {$ R ?/ P6 e( e0 M4 O1 D
- printf("connect() error\n");# p4 x9 ?% P% G
- exit(1);0 z$ U' F% y0 M# d. }
- }
+ s9 U9 ~" G9 f. n7 W - : h8 N& q( f* |1 h T
- char str[] = "horst\n"
5 V: g; t% _0 U
1 V, B; e. V" n" q6 c: |' H! ?- if((num=send(sockfd,str,sizeof(str),0))==-1){( ]& g+ v: f. I- s2 R3 f
- printf("send() error\n");; N" S& `* m( l) w& ]& R0 h! ]
- exit(1);0 Y. e# V& ]7 N& H `. \# `
- }
, Z3 C& s% b% H5 K) L% z - if((num=recv(sockfd,buf,MAXDATASIZE,0))==-1)
% R+ s& P" {1 v2 r& p' T/ E& a - {
: V6 J$ M. G; c. ^9 n0 R' ~ - printf("recv() error\n");2 }" [) A" u! i! q
- exit(1);
' C; d7 |3 y( y0 Y* B% _& D - }
5 \- @( p9 a" ~& R- H- j( G( b8 k - buf[num-1]='\0';4 x3 O) b: X- `8 E7 U9 B, f
- printf("server message: %s\n",buf);6 F2 `3 S" J. }# i4 ~! T+ [) {
- close(sockfd);
! g \. C- L' f7 }% F - return 0;, }* l5 n8 n3 q
- }
复制代码 (2)服务器端,编写server.c,内容如下
) |1 _0 f& }& L- #include <sys/time.h>7 W5 z/ l3 Z% v8 w+ T
- #include <stdlib.h>
1 n3 }$ o4 R+ }6 ~2 B* F. ? - #include <stdio.h># ?' a. `# s! a% ]+ d4 i
- #include <string.h>
. V( P0 p Z! R" }) F* S8 j+ i - #include <unistd.h>+ |' j/ r0 {4 ~- F6 s- S
- #include <sys/types.h>4 K3 D' S" O) K, ?' G. a2 a9 h
- #include <sys/socket.h>' O$ c/ Y5 F, _( L# t
- #include <netinet/in.h>6 |' s1 \8 ~* K9 c
- #include <arpa/inet.h>
# a/ a4 e% B, m; l0 ]& d# E - 1 G+ x) S) F0 |. p9 f: A
- #define PORT 4321
" M6 y5 a4 K% T/ o0 M* c
9 J3 e7 ^- f) v0 A- #define BACKLOG 1+ B$ y3 F; i1 [4 m% y% g
- #define MAXRECVLEN 1024
0 R: Y) X& j3 |+ n
, J6 y. R0 X3 M4 j- int main(int argc, char *argv[])+ i* P6 l' N6 A) x* s0 v5 i6 d
- {
9 g& z ~3 I0 N - char buf[MAXRECVLEN];
. a+ L! J6 j5 j8 u% Y& ^. o' B+ R - int listenfd, connectfd; /* socket descriptors */$ v( l. d( V" h' A w$ D
- struct sockaddr_in server; /* server's address information */# ~ @# s, h- k7 v i) S
- struct sockaddr_in client; /* client's address information */
- w- l# Z4 }% u G - socklen_t addrlen;
( f% H: ^; Z! ] - /* Create TCP socket */
$ F: `+ z" t! o) }3 e% k2 r# [) } - if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)4 y8 i5 u5 n0 W8 e
- {
0 i& q7 f- N& R - /* handle exception */
* V! m1 q0 n8 {7 Q' u- q - perror("socket() error. Failed to initiate a socket");
& q0 i" L3 P; {" C! J( g1 A6 E - exit(1);
2 C% X+ Q/ r" c2 y9 f# ~3 L" z% @ - }
x9 \6 R$ d: q( ^ - 5 e2 d: W! O V) s$ |0 G
- /* set socket option */3 r5 {+ u3 w" y
- int opt = SO_REUSEADDR;! L5 H# x3 f5 b. s# }" J Q
- setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));+ K5 t. e/ v* a; T- s) U* i, D
- ; h- Z K4 {4 g G" [
- bzero(&server, sizeof(server));) k* X9 U a: v
- " m `2 C5 P& R# ]' r" f3 c* |
- server.sin_family = AF_INET;2 ?0 u2 _- c) ^1 `0 p, p
- server.sin_port = htons(PORT);
# b. H# T1 D* d( h& W6 _ B - server.sin_addr.s_addr = htonl(INADDR_ANY);
, @# r, J$ m6 W - if(bind(listenfd, (struct sockaddr *)&server, sizeof(server)) == -1)
" t# h. H) [' u3 v - {
/ M; ]' g% c* K: _0 x - /* handle exception */0 c D/ W7 \* C" E) B
- perror("Bind() error.");
% c3 t4 @- x2 l* g z" ? - exit(1);0 F" X- Q% {4 Z6 H
- }2 H2 A( X* B. U' R) c6 ]: C
- 5 D& x4 }; Z' c9 N' k0 `/ u
- if(listen(listenfd, BACKLOG) == -1)
. q9 z7 z$ K1 w7 } - {
0 X, h1 Q/ j, p( _ - perror("listen() error. \n");9 n" y+ q5 g+ Y: m: l. x$ a4 \5 [
- exit(1);
8 X$ g( o4 j5 B2 [+ z+ V h" v - }
4 U9 F8 Z5 N0 r3 I5 Q- } - ( y/ ^0 e2 u: u- h
- addrlen = sizeof(client); N. H$ e, _+ `4 d
- while(1){
/ `" x! A$ V1 P; l' k5 R4 q( S; s - if((connectfd=accept(listenfd,(struct sockaddr *)&client, &addrlen))==-1)9 Z7 T# v( [. d
- {7 o3 g; O! ?$ h G
- perror("accept() error. \n");. C# m9 b' C9 n' O3 V8 \4 T/ a" X
- exit(1);
% Z& e. X2 j& l3 s* B2 l7 s - }/ U+ @, Z# @) t* Z6 L- o$ v4 s
/ P4 S; ]1 Z) l: d2 j- struct timeval tv;
' c0 _4 E: y) T - gettimeofday(&tv, NULL);1 p7 X+ V$ u/ x
- 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);
" Q/ {+ `! |1 x/ H - ( L* I! R9 D9 R8 i7 h- v
- int iret=-1;
( [! L; K. W- {; B0 ~& f - while(1)
. W. J7 s7 N( S4 ]( f( M+ M - {
" @! t. y' d& b7 @ X4 b$ F - iret = recv(connectfd, buf, MAXRECVLEN, 0);* {9 B& G! o1 L; c/ C
- if(iret>0)
1 k. c. l. Q1 D7 S - {1 Z' k5 C; j4 E
- printf("%s\n", buf);
! q; K3 s, i' A) H5 t: M4 ` - }else
~+ a# W* m, V3 N: ^$ g6 B - {
" r3 ]4 R/ K1 t! M - close(connectfd);
* b& U w' Y# R4 @8 c: G - break;
6 V$ G. d9 Q4 | Z! W5 f - }( Q; e2 q5 ~3 Z1 l2 k( [/ R0 X
- /* print client's ip and port */
, o! [$ @/ w; y3 W - send(connectfd, buf, iret, 0); /* send to the client welcome message */
$ q% c F9 e: a$ ~/ Q' E- I - }6 x( K4 F) g; I
- }
9 i4 J6 A! [; m3 X! z& _- X. P; E- @ - close(listenfd); /* close listenfd */
1 B3 U0 n% e0 c4 g" _ - return 0;' z* I2 s2 f% H# }0 _0 l+ b* ?# e
- }
复制代码 ' G- L& L" ` m* Q* ^' t
- f( @3 u- g0 T. n
(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# `0 g D/ P% l1 ?1 l
1 k8 Q% s6 p" R1 s- server message:horst
复制代码 " S1 g s, \. D! i- A5 a- w
服务器端:
- $./server4 ], {0 k+ {! s5 e
- 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端口等待下一次连接。
2 T1 s4 F8 e! A+ D1 K: p7 u. e: ] d# u
! @+ ?# D( }& |5 X/ |$ S7 D+ P% ^& n; b! j' Q, p% V
作者: admin 时间: 2020-5-9 01:48
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段.! v$ ?/ ]! m n' U0 Z
- /*client.c*/" J U' v$ t/ T. e$ x
- #include<netinet/in.h> // for sockaddr_in ) X# h/ a! e. P" Y7 z6 a" E
- #include<sys/types.h> // for socket
2 q6 B" j$ U& n, F( N( X/ ~$ D# X - #include<sys/socket.h> // for socket
3 h5 F5 Z- a- t. s - #include<stdio.h> // for printf
# r6 [+ y1 T, z - #include<stdlib.h> // for exit 4 F* K0 g( T+ d, M
- #include<string.h> // for bzero
; N' c8 A8 T; E2 ?6 L
5 v# l% m( d/ J$ T$ h/ }- #define HELLO_WORLD_SERVER_PORT 6666 3 U1 n9 ~, Q6 D, `( `" X
- #define BUFFER_SIZE 1024 ! O% V+ N( G/ E
- #define FILE_NAME_MAX_SIZE 512
! Q# P8 O( \' |$ ^# c
. j: }/ B9 c. e* q6 i- R) v- int main(int argc, char **argv) 9 z+ O! Y. r5 I# C
- {
! x4 f' J0 L3 N - if (argc != 2)
7 m8 a W4 Q2 B - { L) y1 m: B$ i; J( l' D- j
- printf("Usage: ./%s ServerIPAddress\n", argv[0]);
: R# D. N$ u, e. W6 `2 v - exit(1);
r, j# D0 Q; d: k - } ! M8 l2 {0 T( F* W- l( O, t
0 p, e) W" K- T2 h3 V1 p% k- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口 - C* p6 K& E3 w% L
- struct sockaddr_in client_addr; ' O: W: r+ D0 U. J) ?
- bzero(&client_addr, sizeof(client_addr)); 1 |* l$ N0 x, q) @, A' ^
- client_addr.sin_family = AF_INET; // internet协议族 3 B: \0 h$ Q& m/ X( N$ i, ~5 M# `
- client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址 * s# U+ J4 i; x; B% `" e3 n* w+ J
- client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口
" a g* k: ]) B4 [; l! b Y
3 l5 l7 }9 l& Q- X7 `$ D f5 n' ?- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket 0 O6 X3 w& H' r! m
- int client_socket = socket(AF_INET, SOCK_STREAM, 0); ! @* d# t$ w' {2 f! P R N
- if (client_socket < 0)
7 B' U [9 ?2 g: x/ p2 m/ S - { % Y; b5 E0 g' l+ r
- printf("Create Socket Failed!\n"); 6 {! D$ M' ^( t* Z; b' j/ v- O
- exit(1);
+ H9 M0 h# i$ a6 z# H. u/ g+ v - } 5 p8 G$ V% P& X: [# V) i6 A
- 6 @3 g5 b% [. s6 k
- // 把客户端的socket和客户端的socket地址结构绑定 4 E2 G1 U3 o. l0 ~2 c
- if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr)))
) r' S; J) H1 X - {
9 X; e: V& I3 s3 n - printf("Client Bind Port Failed!\n");
/ }9 N, h- j! i' G/ ` - exit(1); * U/ O3 X( k8 h
- } - u& [* f( L; V2 ]/ j9 h- ~
- ( e: O5 E6 ^- f+ p
- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口
7 {* u( a2 z, a2 n6 M - struct sockaddr_in server_addr;
8 T& g' P; b% l5 A, ]) G( n - bzero(&server_addr, sizeof(server_addr));
: p5 R' @, b9 ]5 z; Z% K# W. m+ I8 ^ - server_addr.sin_family = AF_INET; 1 U0 ?6 B' v( n7 K1 c
- - N8 d$ z; C4 P; J0 k1 E1 r
- // 服务器的IP地址来自程序的参数
4 @2 A9 z1 b a; \1 f' C - if (inet_aton(argv[1], &server_addr.sin_addr) == 0) ' B# J# {6 I2 y3 ^
- {
, i+ Z5 }% Z) e - printf("Server IP Address Error!\n");
- _. H/ K5 w* l - exit(1);
. b' {5 L# S2 g/ J F - } 9 |+ A, l7 i: Q" W! ~9 M1 h3 U
+ _- _1 f z+ [; {# j* M- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT); * e# B! x1 @* l
- socklen_t server_addr_length = sizeof(server_addr); ( H8 o/ W. M8 g
- 5 O/ \9 N9 ~9 F, u' k5 I% u3 M, T
- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接 : P3 r. k0 I' O& N% p
- if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0)
7 l* Y6 [" d2 G - {
" W7 W6 s$ k- j0 k' M - printf("Can Not Connect To %s!\n", argv[1]); O$ { T$ Y; j1 B+ E
- exit(1);
A* E" i( \% V. \$ z - }
& Y: q3 O5 }( \2 T' M) G4 Y2 ?
& i% m5 {! d& R3 }* I3 a- char file_name[FILE_NAME_MAX_SIZE + 1];
6 V7 y: l) B5 a6 h$ j( q) V! m6 C% | - bzero(file_name, sizeof(file_name));
1 z$ B" y, [2 {/ c+ e- J) L( P8 x0 L - printf("Please Input File Name On Server.\t"); : _0 l8 Z; N9 {) {6 F' P
- scanf("%s", file_name);
4 k9 [9 {* k7 _ h0 [, t; E - - v, U) P% X; ~; G- P2 s# E
- char buffer[BUFFER_SIZE]; 5 c8 y/ B; G2 }- @: l
- bzero(buffer, sizeof(buffer)); 7 b6 h; x/ p! D* U$ M
- strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name)); y5 J8 m ]+ V4 h: w& k+ e
- // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字
q, ?: d" d, Z* X8 _7 m8 K - send(client_socket, buffer, BUFFER_SIZE, 0); 5 e. H# X, N3 y/ y
4 Z- S, {( L. ?, O* r( h% I0 {# @- FILE *fp = fopen(file_name, "w"); ( M: J1 k! @% q& S: z
- if (fp == NULL) / k$ \7 u e& p6 T
- { 9 `3 A: _5 ~: R b# F
- printf("File:\t%s Can Not Open To Write!\n", file_name); ! D5 }; a1 \' J8 {% e
- exit(1);
6 D6 V3 J% l* V4 |, t8 g - } ' k: {& S# v+ ]+ W9 P
- ( d5 y7 z/ ?# B! U3 F, x0 h) I
- // 从服务器端接收数据到buffer中 ( E2 D7 Q5 C2 J
- bzero(buffer, sizeof(buffer)); 4 f9 Z) @$ ?) j5 {4 K' {- p0 D
- int length = 0;
+ s! F* K! D* @1 D0 [ - while(length = recv(client_socket, buffer, BUFFER_SIZE, 0))
; G' T& @4 y" O! ?. i, {. c - { % ^* C; }( E p3 @0 H
- if (length < 0)
. J7 d& r3 {9 D7 t$ R [3 R8 j6 Z - {
; ?+ D' U2 p$ M+ v |* w: J' f - printf("Recieve Data From Server %s Failed!\n", argv[1]);
8 y @" d1 w& W p5 V) ~ - break; - i7 u/ c7 V" U7 Q9 c- i
- } 5 f/ o7 H8 |# Z7 G7 \
5 E/ t3 l1 c6 S3 V4 d) L7 F" }2 `- int write_length = fwrite(buffer, sizeof(char), length, fp);
7 z: B/ S8 ]9 ] - if (write_length < length) , g+ \3 s) X4 r& i
- { , M. m2 F0 f$ s. m& k. w! z- K: M
- printf("File:\t%s Write Failed!\n", file_name); + L& E- A( P. B1 z
- break; # q( v* e K* y7 w. L
- } . C9 S9 K0 C3 ?5 A
- bzero(buffer, BUFFER_SIZE);
5 {3 E, [& O: E7 r, J0 v2 h9 Y - } ! Z5 q; @- c! f* ~' Z* d
% Q" G7 J; F, _- Y% l5 Z7 b- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]);
W* q# @! X- ]5 X4 l( n, c) U2 A
4 i0 ]& j! E5 _1 Y0 u8 n- // 传输完毕,关闭socket : \2 z" {) D& s4 ]
- fclose(fp); 6 b" t: X& h" `0 p( z+ M* o7 |
- close(client_socket); 2 [. F4 Y; a$ q
- return 0; 5 y Z1 u. R3 Y. @
2 \/ E$ ^4 F6 E+ W- }
4 Z3 q9 ^7 n" F6 p ~ - # I- r) |/ R/ G) ^# ?
复制代码- /*server.c*/
9 d& N: [/ k4 v - #include<netinet/in.h>
5 @3 f% I. M% A! X2 u - #include<sys/types.h>' w: [0 x/ J$ g; L) P) Y
- #include<sys/socket.h>6 N7 |& ]: ~! O2 |9 K1 X, x' I
- #include<stdio.h>
, e% K7 ~5 A1 p# D' v d - #include<stdlib.h>
* I9 i. R8 ]% T0 U - #include<string.h>/ e, v1 R2 b5 \( B* ~
6 I3 F& c7 e; r( |/ G K3 v, K5 h- #define HELLO_WORLD_SERVER_PORT 6666 //端口号
: U( }0 I# S3 l& n) j# m: r - #define LENGTH_OF_LISTEN_QUEUE 20: r8 `+ @2 e& J- o4 _2 Q" A, z
- #define BUFFER_SIZE 1024
9 \! b% \, ?; ?- h - #define FILE_NAME_MAX_SIZE 512
9 r' ^- w! j0 V" {0 i2 w, e& \
0 v" d6 y; s2 G1 y- int main(int argc, char **argv)
3 y4 I j4 H$ f0 r7 m - {
- b* O2 `1 k. Q) @6 T5 H! W$ m9 \ - // set socket's address information5 {* s" q7 w# u! E2 u; Y, n
- // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口
# W6 J8 T( Q! n4 _% J- R' V9 A - struct sockaddr_in server_addr;
1 T2 ]' h, R P# ?/ ?! o - bzero(&server_addr, sizeof(server_addr));6 D* V% m1 `1 ? d5 o- w' _& U
- server_addr.sin_family = AF_INET;7 r, R( X& o8 r
- server_addr.sin_addr.s_addr = htons(INADDR_ANY);/ @ b% ` Z6 x7 s, l
- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
0 `! G$ y3 N8 v: L" `8 s" k q! N: t
- H1 B5 I, x& j, Z- // create a stream socket# j# z$ D" F. x0 @9 i8 s) J
- // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口- X) }- w6 G6 p# y' k- B
- int server_socket = socket(PF_INET, SOCK_STREAM, 0);
7 X# w4 k2 f' T5 n - if (server_socket < 0)
3 Y" g9 C: C/ ~6 p - {
j7 v& W H$ j - printf("Create Socket Failed!\n");& T/ O* ?" A7 Q; J9 B) I# ]0 D' v& P+ y
- exit(1);2 V2 Q1 R1 _* a2 g) d0 _& g( @
- }9 i% V1 t. ^6 K; J( k. B4 z
9 K" i% ]( j- X5 C1 H' B- // 把socket和socket地址结构绑定" m1 f2 @/ U/ j/ H8 e
- if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))7 h1 N4 [; O1 _9 ?1 W
- {3 |( l0 ?$ c3 K( ?
- printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);% q' A/ J# ^9 v+ [/ }
- exit(1);4 H: x3 s' @2 T2 x- \$ d
- }
5 [% m1 h* d. J1 h5 ~2 y- c - 2 j8 W0 C( |) D3 B
- // server_socket用于监听
: r( Z1 v4 v! L - if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))
: W9 D. k" b1 |% i. v% b - {0 S+ A) i4 _" n1 m" j
- printf("Server Listen Failed!\n");
: s; z. X0 H: Y u% k - exit(1);, e& Y) x; ?0 Q
- } g" X9 X4 P7 O8 Z7 A- [" Y6 x6 E, }8 W
- $ @6 B1 K8 Y5 H! @, h
- // 服务器端一直运行用以持续为客户端提供服务
& M) \1 j4 |3 j3 g( V% V4 r5 H - while(1) Z, u" T$ }- b r2 I6 C
- {
+ ?( i' j7 W# E. q" L - // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept
8 g: {2 d* `3 l8 L - // 接受此请求,同时将client端的地址和端口等信息写入client_addr中+ F' S. @5 n+ j/ |; r! C" t
- struct sockaddr_in client_addr;) J+ s! L$ ~% V( t
- socklen_t length = sizeof(client_addr);! }% p! Z) K7 z# W9 H2 _5 ]- @
- . K1 q0 |" A) Y# A" R
- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中/ _! v2 q* W( }" Z! p
- // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以. D5 [; l8 i- }
- // 用select()来实现超时检测
( n) [; a6 ~- P1 W5 d7 m. y- ] - // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信4 X$ k; e" a2 M
- // 这里的new_server_socket代表了这个通信通道
1 U9 U" j1 G" u - int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);& {! \ g0 }5 |, s
- if (new_server_socket < 0)
' m. a1 H' ], @; z4 s4 k# J, z - {
8 b. \! [, e, @4 \+ f - printf("Server Accept Failed!\n");# S" ~* G- x& b8 h
- break;0 s! g% C8 @/ m; m
- }% J$ V+ ~( C& w9 c
- : u7 i) E; H( A% Y
- char buffer[BUFFER_SIZE];$ M: p. x8 s/ X. S# y& M
- bzero(buffer, sizeof(buffer));, Y( K! m' X& B" p! p, j4 C
- length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);
2 U- T, B$ i! K6 S% Z+ s0 o - if (length < 0)( K6 B1 [. T+ B8 j
- {$ p& p* I+ o6 d `8 Q( L* U& @
- printf("Server Recieve Data Failed!\n");/ |) c3 [( Z5 R/ J; p
- break;
+ F9 j5 ^" B5 P8 Y( { - }; l$ D+ Z& l& I* T {
0 z! [) F0 ]) N/ t, Q" x* n9 z- a- char file_name[FILE_NAME_MAX_SIZE + 1];! s5 a9 h- h5 j5 P# ^
- bzero(file_name, sizeof(file_name));
5 m3 J9 O& \& J' C, v+ ]6 O7 J9 M - strncpy(file_name, buffer,( p& U3 _4 J) w W/ {
- strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));
0 {; u! a( Q5 e8 u; \( U - + E# ^+ T# |: R" S% b! Z4 ]9 {" L: D
- FILE *fp = fopen(file_name, "r");# i+ a* B) H8 r2 @8 i
- if (fp == NULL)( N2 z7 M' |+ o3 {
- {1 l2 i4 C8 V, c+ V
- printf("File:\t%s Not Found!\n", file_name);, i% @3 p1 G- V1 D' f; L
- }1 r) H! c$ \1 H" b( Z
- else
* d! ?) ]! _7 P" M) }& [ - {
6 E0 v7 _6 T) e. l& r; v - bzero(buffer, BUFFER_SIZE);
+ k* B4 c1 A: K, Q - int file_block_length = 0;
. N% r) F, T N+ t- x# N8 ^ - while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
& S4 W A) P! ~4 r! x3 O, j - {
* C; G5 x2 F4 x - printf("file_block_length = %d\n", file_block_length);4 U/ k. Q& h9 @, B4 I3 h: G3 b
- ' Q9 ?# J7 R. p$ E9 T1 c: L
- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端
3 z$ ^' r4 w6 w# M - if (send(new_server_socket, buffer, file_block_length, 0) < 0)
" Z+ _4 }/ Q$ ?7 U7 J6 a: K - {9 Q& f v" d- W/ {5 N! w
- printf("Send File:\t%s Failed!\n", file_name);
) \ _: B3 P2 p/ Y - break;3 s; x1 Z+ W+ k. P C& J/ e
- }
. z4 d1 h+ M8 m: a( @ - j ~/ Q" s0 n
- bzero(buffer, sizeof(buffer));
1 ~' L# D. z) z* l. o - }: H; m) ]8 ]0 u9 V
- fclose(fp); R0 }( `6 D. u8 d6 i
- printf("File:\t%s Transfer Finished!\n", file_name);: H" a: U" r2 E" {! p, B, B
- }
! C" O+ f: Y( P. _! A/ K
' f H/ y, a8 w/ t z- close(new_server_socket);, ]8 m! ~$ q: S% \7 I9 S& Y! @
- }" s: J4 e# v1 l0 A, @
- w1 g! ?, A, {" r# I& G4 R: t W
- close(server_socket);
5 H v6 T6 z4 j' D* L# G: \ - 5 }* L2 p+ \9 c; K- Z; Z
- return 0;; T/ u3 l3 ?, H3 |: k
- }
; d. B2 H1 b% F4 }- F - . `3 q- n7 r8 R8 ^8 M: f- x
复制代码
\ e2 a5 Q8 R( `7 Z. S/ X0 E% g% d! A8 o2 _4 w7 w
4 b, I: k$ }1 y K% T7 X, I: g
( Y! t+ M, Y* V' p) A# S
欢迎光临 cncml手绘网 (http://www.cncml.com/) |
Powered by Discuz! X3.2 |