cncml手绘网
标题: 一个很实用的服务端和客户端进行TCP通信的实例 [打印本页]
作者: admin 时间: 2020-5-9 01:46
标题: 一个很实用的服务端和客户端进行TCP通信的实例
本文给出一个很实用的服务端和客户端进行TCP通信的小例子。具体实现上非常简单,只是平时编写类似程序,具体步骤经常忘记,还要总是查,暂且将其记下来,方便以后参考。. n) ?) O1 N9 C9 I( u1 [9 K1 v: E
(1)客户端程序,编写一个文件client.c,内容如下:
- R8 E: T) L9 ]& u* I- #include <stdlib.h>
0 ~7 D2 V4 ^& l - #include <stdio.h>5 J" N$ \+ }3 {! C2 }& m
- #include <unistd.h>
9 R! p7 H" y" |$ ]# a - #include <string.h>
7 I9 f- A1 c0 D1 R& t - #include <sys/types.h>
* C6 w' C3 K t9 u) E - #include <sys/socket.h>0 T' b) i) A w8 U0 k- [ i) ~7 |
- #include <netinet/in.h>1 u7 y) s4 d) p7 ~
- #include <netdb.h> /* netdb is necessary for struct hostent */
6 o. Y: b& Q+ ]
- e3 D/ F4 G# R; F7 U7 L- #define PORT 4321 /* server port */# C& Y* \9 I q; n
) B# C6 q% ~+ D( g8 e4 d- #define MAXDATASIZE 100& q3 D9 `' |& H5 @- @ e4 S1 `
7 w% a0 q! u. d% k( ~7 @1 E7 j- int main(int argc, char *argv[])
6 a$ B% V- c b* i( ~* W - {
7 _( M7 q" Y/ f. a: p - int sockfd, num; /* files descriptors */9 i/ D' }7 J5 \8 f4 T- `6 o
- char buf[MAXDATASIZE]; /* buf will store received text */
! S2 L3 g: p* T3 W! Y/ M - struct hostent *he; /* structure that will get information about remote host */7 }; D1 t. ]( L3 r& V: S0 _. O
- struct sockaddr_in server;+ L- h5 v9 I( _2 X8 Z
- 7 @ U- a7 Q5 ] D+ @2 m
- if (argc != 2)3 D% v9 H4 H& `& k4 W+ Y- n
- {' s8 G/ p) h* d2 D3 [* X7 @% g
- printf("Usage: %s <IP Address>\n",argv[0]);
. s: I( w" N4 g) z, g1 C2 a3 \0 N6 V - exit(1);
/ E7 J" m4 O3 R! t" n+ T) c - }2 z: {1 f, X: c+ W9 Q
-
$ F& e, G; B- K8 L+ N' E& i - if((he=gethostbyname(argv[1]))==NULL): w7 e9 B3 R0 {
- {
' W3 i) ?8 l: K2 R! k; e - printf("gethostbyname() error\n");) J8 |% {! |9 f5 l
- exit(1);
4 ~: _ z) O" O: w - }
7 G/ t; Y1 g, c- k4 L p# ^ -
/ C4 H! Z, X! ]$ m* N" K8 d% W" y$ P - if((sockfd=socket(AF_INET,SOCK_STREAM, 0))==-1)4 O3 q7 M+ z( n8 ]; D$ [: e1 l* ?/ k
- {7 D1 U. z4 F4 d; ?$ J
- printf("socket() error\n");; p) I+ q% c6 n7 t: u
- exit(1);+ C( k! v1 ~; E1 q8 u' y
- }, d ]+ w: e: v8 D: i5 u+ z3 ~3 N
- bzero(&server,sizeof(server));
. h+ f2 L2 y3 i- u+ K0 \% q - server.sin_family = AF_INET;
) x" C* k+ m! ^ - server.sin_port = htons(PORT);' n3 K; h* `. \9 v6 @1 \
- server.sin_addr = *((struct in_addr *)he->h_addr);
$ H6 U. V# {. N% O - if(connect(sockfd, (struct sockaddr *)&server, sizeof(server))==-1)
# E, B Y( V: O6 R - {
7 j* M. b- B0 l! B1 R; l - printf("connect() error\n");
# d9 Q' L- x$ `3 d- F! J& p( W( ? - exit(1);
7 K7 N3 p# ?5 J+ e% Y - }& X- @9 g! v( |) v; X
- ) a$ j) i0 y5 E1 r1 D5 L( v% v
- char str[] = "horst\n"* @( T/ v+ `7 b/ c
" H: k8 T$ f" n3 o. e- if((num=send(sockfd,str,sizeof(str),0))==-1){
7 \' M# \3 i4 \: t; J, l8 D" ] - printf("send() error\n");' I3 F5 e! q7 p' b N% `
- exit(1);
. V+ }, U8 ]# i7 z - }
/ p, ]7 a1 t1 R! ? - if((num=recv(sockfd,buf,MAXDATASIZE,0))==-1)
3 x# |0 y5 B4 M - {, Z3 z3 V7 |: F/ p) _; `1 o7 ]
- printf("recv() error\n");0 d- j) U+ A+ q0 R4 I
- exit(1);
3 _$ o% W: v+ u, Y. V5 ?+ o& Q+ l - }
, u8 t$ Q0 `! }3 @ - buf[num-1]='\0';- e8 o. G; K9 Q: W
- printf("server message: %s\n",buf);
8 [6 V& c- E0 A/ l, g8 E - close(sockfd);
; D+ Z/ E$ A9 [8 w8 w - return 0;5 e6 B# _& D T8 I3 e8 k) I
- }
复制代码 (2)服务器端,编写server.c,内容如下. n" ?! C* ^% T! ]2 h/ p. ]+ e) W" h
- #include <sys/time.h># S# {7 B6 j' ]" i9 Y
- #include <stdlib.h># a" A' Z: F4 A
- #include <stdio.h>. j3 @6 Z% a4 i) ], r
- #include <string.h>9 d" {1 H* V/ U6 x* g W1 S( E1 J
- #include <unistd.h>+ I, T2 m& ~; T
- #include <sys/types.h>
7 B! \- C; `6 Q& l - #include <sys/socket.h>( t- `5 ]4 Y+ T
- #include <netinet/in.h>
1 \: x! v2 H- S3 m4 [& d - #include <arpa/inet.h>
, m, F4 [. ~1 a) d0 [7 c8 [. l
9 B# Y4 ^, a4 |! [! p( I& v- H- #define PORT 4321
+ L/ w6 d( k8 h7 U8 T# c! x- l
) E/ L6 W6 e2 f. |& I- #define BACKLOG 1
/ i4 o, A' B1 P. U - #define MAXRECVLEN 10242 `5 S! M8 `. |
% S n0 o5 T! h+ A' u+ ^- int main(int argc, char *argv[])$ @7 [5 m3 i0 D4 |9 A9 B
- {
4 }) a% |1 d3 \. b - char buf[MAXRECVLEN];
, g/ i% R9 X1 v) k/ P5 Q - int listenfd, connectfd; /* socket descriptors */
& P z: d- R7 [, @) M3 J E - struct sockaddr_in server; /* server's address information */: ^. U9 X0 m7 }5 ~: c: m
- struct sockaddr_in client; /* client's address information */* g3 F. g6 ]& d2 y
- socklen_t addrlen;8 R7 }9 B3 I6 y e, C! T$ x3 {3 r
- /* Create TCP socket */
. d) Y. R8 p! [ i - if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
( m- m C" N" r+ {- H - {" w9 I1 I [! l* W/ }8 r
- /* handle exception */+ E" U2 u; V) c6 ^. k8 `- H
- perror("socket() error. Failed to initiate a socket");' k( K3 }& x( u! a6 n
- exit(1);
5 `- B& V: A$ m1 A" F. ?0 B3 d - }
' p- d" V9 J0 g- _ - 1 J, S# t9 G( p* T) n' X8 U
- /* set socket option */
, e4 ]' R% s% P) e) I# z/ @ - int opt = SO_REUSEADDR;( R' s+ Y$ z! Z Q' D; \5 s
- setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));! Q2 X5 n+ r8 g& N0 S$ X
- " v; Q0 E- I9 i& \4 _1 }
- bzero(&server, sizeof(server));0 O9 f8 y0 N A5 y3 i; s3 A: O
5 f9 }+ V& S9 H5 l- server.sin_family = AF_INET;
f% D* p8 S# F& F# q* |; n - server.sin_port = htons(PORT);
" q! J% k8 N/ e. h' | - server.sin_addr.s_addr = htonl(INADDR_ANY);
/ j6 t6 |' f. X& p/ R5 x - if(bind(listenfd, (struct sockaddr *)&server, sizeof(server)) == -1)
5 T* N. Q% }0 U6 d; }, A6 L$ u: i - {: f' \2 ]# `7 m3 I+ D$ j/ V6 q
- /* handle exception */% p& @' w, D$ q$ a/ w) {0 y
- perror("Bind() error.");' h4 u3 n; j/ B+ K3 ^
- exit(1);1 } f3 E. L$ J1 s! c1 R0 z7 r! c
- }
6 D- h( w' s- m1 K - $ k% \8 H' ^2 C M& E9 @
- if(listen(listenfd, BACKLOG) == -1)/ h6 R6 P% u5 p& F3 w% P y2 ?, u
- {$ ~% H# c( r: F# V. A1 }
- perror("listen() error. \n");* |/ ~& T G2 x! X+ u) x
- exit(1);+ E9 p2 F% n) @; r
- }
) {, q6 M- L: K- W8 c8 J - 8 {$ J; h( g8 W9 e
- addrlen = sizeof(client);
9 \/ [. c$ @: H6 @* h0 Q5 ? - while(1){
, [2 K7 J& m4 ~/ [! L4 d& L - if((connectfd=accept(listenfd,(struct sockaddr *)&client, &addrlen))==-1)
4 ]4 ^2 U% C# l$ u e I - {
5 T" W# a+ _, i. e7 L! G - perror("accept() error. \n");* }- H! y* q3 ~( u- W1 _
- exit(1);- ?. w) O9 [+ O6 s; r6 r h5 {
- } L$ w! N6 U. J* A
- + ^" {1 R+ B# }) X0 K1 ~: j* W
- struct timeval tv;$ N6 t: {2 y9 J2 H
- gettimeofday(&tv, NULL);' N, N' Q d1 h* r- i
- 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);# b2 Y6 h' P) c4 b4 x& ]) ?
-
/ G! f' h! B5 q$ v - int iret=-1;* R) q* W& s6 c3 @( ~$ X
- while(1)* W, U. p! p! c8 x
- {& ^- f9 V# U* O. l# W/ j& R( _
- iret = recv(connectfd, buf, MAXRECVLEN, 0);
) z+ D; g, i& b- }5 |" _7 p - if(iret>0)* I' @) }8 j/ f8 J
- {
9 e7 G; K. c( m7 q, H0 M - printf("%s\n", buf);
0 C$ E* A. J; ]4 w$ ^7 } - }else5 ?7 g9 r6 }9 q% C$ `
- {$ _* k9 \ K' t# l
- close(connectfd);
6 t, U: P: \$ a9 b' z. ^7 V! F4 h - break;+ m4 J# r8 d8 e5 D2 u; I/ r; \" k
- }
; o( q- x' }2 [' x1 M2 R5 t - /* print client's ip and port */
, S9 f9 V N) p3 \! M - send(connectfd, buf, iret, 0); /* send to the client welcome message */
. l9 G1 k: ~: B$ q% j3 ~7 F - }: C5 a: n* ?; C3 @: @" m
- }- A s7 Q0 k; O% ?' C* N
- close(listenfd); /* close listenfd */* K: r$ @$ w2 B! E1 M5 B
- return 0;
- J) x5 _5 D7 Y* g - }
复制代码
' }. t( d# ~/ Q4 h; g$ J, x! u# d+ ?; }' z' f( ]
(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; g$ X* c5 C( r% ^* T
7 Z2 W0 M X" h, p9 C" U- T/ S- server message:horst
复制代码
6 s; Z& ?' F O( b服务器端:
- $./server7 j0 d2 ]0 S& c1 l& A& W
- 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端口等待下一次连接。
* @3 y" O" n' i* I. l
: T) D$ s! e9 L) e2 ^7 Q, k# d K7 }* Z, G3 { q# l" C4 E5 j
& n% L# O; e8 \. |
作者: admin 时间: 2020-5-9 01:48
服务端启动,客户端通过ip地址连接服务端,然后输入要发送的文件名,发送文件到服务段./ u5 b4 N) N( y6 a
- /*client.c*/
+ {3 D5 @# i% @& | - #include<netinet/in.h> // for sockaddr_in ! L: z6 c' A9 O' e
- #include<sys/types.h> // for socket $ Z5 q! E) y4 f& {5 S+ R6 F
- #include<sys/socket.h> // for socket 2 U, r9 A* w2 @
- #include<stdio.h> // for printf
. Q% l J2 w- L9 L9 C0 Z - #include<stdlib.h> // for exit " g3 u5 B9 N' |
- #include<string.h> // for bzero 2 T1 q. l. }7 S; B
- , s J5 V# S5 _ F" Q: F
- #define HELLO_WORLD_SERVER_PORT 6666
. \ X, B/ H- [) ^% j, @ - #define BUFFER_SIZE 1024 ( E2 q$ w3 H/ F* X; a
- #define FILE_NAME_MAX_SIZE 512
% V& x: j% x3 q, B1 S
* R/ _) u" k2 t5 t- l, p1 C( j2 b- int main(int argc, char **argv)
: q: N* S6 n9 v e* S+ W- E* f. P - {
6 k& D ^% D: |; I, i - if (argc != 2)
$ o! M6 N1 n( ]) w - {
* i' e2 ]" I' B# c# e6 w - printf("Usage: ./%s ServerIPAddress\n", argv[0]);
, k e$ R4 \/ ^3 I - exit(1); 4 W( C1 T6 F6 _# b* E" ?8 v
- }
1 R9 \7 [" k. W
0 U3 m6 X* d; W- c& f/ ^- // 设置一个socket地址结构client_addr, 代表客户机的internet地址和端口 6 ?; D3 s6 J, }- n% l; ~
- struct sockaddr_in client_addr;
7 W* V5 q3 C4 V - bzero(&client_addr, sizeof(client_addr)); & ?8 P# I! n- I1 u, A+ r
- client_addr.sin_family = AF_INET; // internet协议族
( @* g. E6 {2 S! s - client_addr.sin_addr.s_addr = htons(INADDR_ANY); // INADDR_ANY表示自动获取本机地址 ) B, a& w* t7 w4 @* _7 l( G3 x* Z
- client_addr.sin_port = htons(0); // auto allocated, 让系统自动分配一个空闲端口
8 V' }9 S& \" W3 V* `, j) I5 C. Z
; z# n+ s' p7 w- // 创建用于internet的流协议(TCP)类型socket,用client_socket代表客户端socket 8 Y% _2 ^: x- v* i J8 {, C
- int client_socket = socket(AF_INET, SOCK_STREAM, 0); . N6 q& w& Q: P( @# Q+ T6 {
- if (client_socket < 0) 6 f; O9 k4 _% \1 E# c
- {
N* R9 G: N/ U; A" C - printf("Create Socket Failed!\n"); o) T. T( J+ `8 }7 A# M+ n( S/ ^% w
- exit(1);
/ N# X* C' n" u2 Z# P+ W - } , J8 ?) ^0 ?; T. \/ b$ @
2 ], h5 v6 e x+ O' l- // 把客户端的socket和客户端的socket地址结构绑定
3 j- V' t2 r. r3 p+ _ H+ c6 w% V - if (bind(client_socket, (struct sockaddr*)&client_addr, sizeof(client_addr))) / r, c# u+ T8 G( z+ ~
- {
4 I* |6 a& ]2 K A6 ? - printf("Client Bind Port Failed!\n"); # `5 T% Y2 G8 ]8 d$ P& F. f$ H
- exit(1); u3 q2 `- ^; A! K( s9 P4 P/ Q# m
- }
7 G- A: e1 _/ f, n
* \, c. X u' J& j/ {- // 设置一个socket地址结构server_addr,代表服务器的internet地址和端口
0 w( X6 s Q2 z4 w' u' L) u - struct sockaddr_in server_addr;
3 [+ ], l# D9 O5 Z - bzero(&server_addr, sizeof(server_addr)); 2 i" v; j8 {/ o; q- @' r5 l' B" H, q
- server_addr.sin_family = AF_INET; r+ a E* f* O/ l) ^9 W# L) ^6 [ ]
1 ?: X2 ]" E0 O0 f- // 服务器的IP地址来自程序的参数 1 M; z* Q0 A3 j' t
- if (inet_aton(argv[1], &server_addr.sin_addr) == 0) # M) Q$ _: |: I; Q [
- { 2 A3 f, y, g0 r* W3 O% L/ G4 m% ~
- printf("Server IP Address Error!\n");
* L* Q+ n }) z5 b) i0 n - exit(1); : P" w6 C& }, c& X% V
- }
+ L" _& e! U* @3 z) e - : A1 }8 l+ M# d7 D* V
- server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
% B3 s2 T5 O6 {, F1 b' u - socklen_t server_addr_length = sizeof(server_addr); ' E" L9 c( l G0 b3 J$ h
; @1 ]0 R- F' g) x- // 向服务器发起连接请求,连接成功后client_socket代表客户端和服务器端的一个socket连接
5 c% I3 w5 i! J/ p S - if (connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length) < 0)
& b2 ], z: K/ T" I3 i; ^ - {
& n! k$ `, u7 @' | - printf("Can Not Connect To %s!\n", argv[1]); , E# C2 T& H, b
- exit(1); , L2 D9 W6 V) B$ x; O, Z2 ~# z
- }
4 h1 t2 D1 ]4 A - - I. I- q# a% ]0 z) c' |
- char file_name[FILE_NAME_MAX_SIZE + 1];
9 u7 l4 O, u+ a; ^2 v - bzero(file_name, sizeof(file_name));
& Q* f% T7 y1 b& q, C - printf("Please Input File Name On Server.\t"); O& L& q. D; \! U* m e
- scanf("%s", file_name); . u! s( L! _% { W
* ]3 A2 w0 j; g" u2 z. N- char buffer[BUFFER_SIZE]; - t1 w5 x* b: A$ ?" s* l) D
- bzero(buffer, sizeof(buffer));
' ] l/ [! v6 A( U - strncpy(buffer, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name));
; z% F; E' @2 Y/ z1 A - // 向服务器发送buffer中的数据,此时buffer中存放的是客户端需要接收的文件的名字 ) b# H. _+ s0 b8 j% _0 m
- send(client_socket, buffer, BUFFER_SIZE, 0); p, Q' K+ W" e% y
" @ u/ j3 v5 ?( q* X4 ^- FILE *fp = fopen(file_name, "w"); ( y2 f2 m! i+ a" J/ U* Q' V# M
- if (fp == NULL) 0 g! s ]9 P, s& {5 }3 U9 r
- { ( b- ?; Z3 Q1 o8 E
- printf("File:\t%s Can Not Open To Write!\n", file_name);
' F) J+ p7 _1 V. ^8 v( _ - exit(1);
% ]0 H0 _6 S* J, K - } % H9 a: ?2 m% u9 G% e, ~
- 0 b0 R+ y% g Q b; _3 p- H
- // 从服务器端接收数据到buffer中 7 Y7 l0 k2 j6 ^% M2 q
- bzero(buffer, sizeof(buffer));
- _, H- a6 _# V1 A: P* ? - int length = 0; ; i! b4 ]% z# Y0 s! E1 w
- while(length = recv(client_socket, buffer, BUFFER_SIZE, 0))
% y6 {/ z: I/ W6 ` L! @4 A - {
2 J( o! j$ a8 M/ G% ]) q; P3 I( F+ g4 T - if (length < 0) 5 B: f0 b3 }/ \ T& c/ P# T1 |" y A" {
- { / o7 X3 C2 c T+ V/ z! Z& t! ~+ n7 V
- printf("Recieve Data From Server %s Failed!\n", argv[1]);
5 P1 Y% x3 c1 _" u. ^- D" [ - break;
; W, f5 w) f) A+ o# d* Y - } ; i. h# ^, R* E. @
# G: t6 {: b$ m- int write_length = fwrite(buffer, sizeof(char), length, fp); 3 j, k% D* p( p$ }2 `: K C
- if (write_length < length)
# O' b+ L# n. c - {
% U N+ Y* I4 q) t* m4 N - printf("File:\t%s Write Failed!\n", file_name); : P& r6 ~7 b% S7 s' s
- break;
! t( H p1 Y: O6 s6 {, q - }
- K$ W9 p( b3 _/ B8 d8 ^ - bzero(buffer, BUFFER_SIZE);
9 c, }# ~. c" L* {% r - } ' H5 n# t! O7 l' h: y; L
- 2 V' d Z! O0 r4 U
- printf("Recieve File:\t %s From Server[%s] Finished!\n", file_name, argv[1]); $ y7 i" U6 M; [$ `
- % g. C% _& R! A7 `) P
- // 传输完毕,关闭socket
6 j* m* m1 }% e7 \5 d3 N6 _ - fclose(fp);
% O0 @/ \) | g7 n+ ~) i/ n - close(client_socket); ( o; j6 R( O. t! J1 z6 J) p
- return 0; 5 o3 x- B* \- T% K2 F+ Q0 q
- ' l0 g. A6 \! o* Z! x
- }
1 m3 E7 u' K* a( Q! p8 A5 c - . n- `! u0 }( ]! f
复制代码- /*server.c*/
1 Y% N! j- Y6 l/ J) |8 K- E, P - #include<netinet/in.h> u1 \) A+ P8 _+ V0 @ i [
- #include<sys/types.h>
2 T/ g3 d0 q0 [ - #include<sys/socket.h>( M; z9 }& ^$ l7 D; c4 `
- #include<stdio.h>
/ \2 Q1 D5 e: C7 F - #include<stdlib.h>. K0 a( x" A# H
- #include<string.h>3 D, l" T& V- E; }0 }( b. U
- C- e6 y& D$ b0 J! b
- #define HELLO_WORLD_SERVER_PORT 6666 //端口号
; W G7 O! m1 ^8 i6 G0 j& g - #define LENGTH_OF_LISTEN_QUEUE 200 t8 k& x8 k1 N1 v- j% Q, l1 |
- #define BUFFER_SIZE 1024- P1 m: O1 @* R; X+ d( t
- #define FILE_NAME_MAX_SIZE 512$ q! P6 J: B( y2 ^* D
! r2 e. ]1 W1 d2 V- int main(int argc, char **argv)5 D$ N. H+ K# d, C. S; p% S7 k
- {" H Y1 u) m- r4 b4 B& K: [) a* M
- // set socket's address information
5 @ |) \/ h5 R2 Z2 {4 \( K3 Y - // 设置一个socket地址结构server_addr,代表服务器internet的地址和端口
. Z; W( i L. G! t' m" | - struct sockaddr_in server_addr;: P- J% P) u$ @4 w5 q; \
- bzero(&server_addr, sizeof(server_addr));- U. A# B% v- B
- server_addr.sin_family = AF_INET;
: I" Q2 f6 p% ^# l9 o - server_addr.sin_addr.s_addr = htons(INADDR_ANY);
; e! @% W4 s5 @ - server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);! L' T8 z# q- C D. W0 P
- 4 [& H9 C/ H4 M9 M4 S1 O' T- l0 M9 j
- // create a stream socket9 w1 T( `- P6 z4 T
- // 创建用于internet的流协议(TCP)socket,用server_socket代表服务器向客户端提供服务的接口
& w1 C. I- | { - int server_socket = socket(PF_INET, SOCK_STREAM, 0);) G4 B3 k( V, Y! j/ @ V8 e
- if (server_socket < 0)
/ a: ?9 k& ?+ D - {
' J, Q v6 m0 A1 j+ Z- a. O7 |6 ]5 _3 Y - printf("Create Socket Failed!\n");; C: u. |0 o: u7 v& w
- exit(1);# Q! |: _$ K2 i+ F$ b0 |
- }$ O" B' J5 ^; j% l" C
( R7 j& ~# v$ y* ?- // 把socket和socket地址结构绑定
1 ]4 C$ c% d" o2 `9 ? - if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr))). d, s9 J( k7 z) m6 q/ _
- {; V: [, [4 U7 [5 ]
- printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);
9 ?9 `- b- \7 Y - exit(1); F# J8 H) Z8 f }2 a6 N
- }
4 I8 k- o- m) m! E5 S. \9 G3 t
$ ~& t3 A( e1 F, n& i+ S- // server_socket用于监听
4 ` e3 A: b& Z - if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))+ ?& k. y' H5 }( H
- {/ T0 s( R: y Y' f8 e1 Q% r
- printf("Server Listen Failed!\n");
' X/ q( K; Q @" V% i( V - exit(1);6 W* _( W4 S: l
- }; ~' B5 X& z' X1 M# m# l h
- $ R5 I0 I: t) b
- // 服务器端一直运行用以持续为客户端提供服务' p1 W2 K. _3 }: D/ @( l$ V8 q7 E# M) Z
- while(1)
0 O5 |: s- o+ p! } - {
; ` v1 F. C7 X# D - // 定义客户端的socket地址结构client_addr,当收到来自客户端的请求后,调用accept3 e7 U- t2 ^& j4 Y: Y6 I/ O
- // 接受此请求,同时将client端的地址和端口等信息写入client_addr中* O$ D$ T! p9 @' N; q+ O
- struct sockaddr_in client_addr;
+ {" M, E) K7 q0 @& S - socklen_t length = sizeof(client_addr);4 ^. U- q! ~6 q, E2 |% m
- 6 Z! _. A" U' j
- // 接受一个从client端到达server端的连接请求,将客户端的信息保存在client_addr中* E g& H2 E m0 `8 H5 [. M+ I4 z
- // 如果没有连接请求,则一直等待直到有连接请求为止,这是accept函数的特性,可以
" B, r- n5 R+ t0 {+ G - // 用select()来实现超时检测
* D8 A9 i8 {- o# Y3 @& I - // accpet返回一个新的socket,这个socket用来与此次连接到server的client进行通信6 H. E# |) z g' n5 S6 q2 g
- // 这里的new_server_socket代表了这个通信通道3 f+ ]3 ]! D5 d, _4 w! U% R
- int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);
2 ]# }- ?0 R, L! E! W - if (new_server_socket < 0)
3 w: j; A1 `% u - {/ f, e. |0 ?9 q3 ]- `; t$ ^
- printf("Server Accept Failed!\n");8 S; t' j( \" u, s
- break;
$ ]7 `8 Z# \9 n' ?1 u% X - }+ g+ M3 y& {) {- R
3 h0 y) J) E& o: w8 f) F- char buffer[BUFFER_SIZE];
1 N" \* ~4 r2 N3 a - bzero(buffer, sizeof(buffer));
! T/ S! @# s# x/ A/ T) D - length = recv(new_server_socket, buffer, BUFFER_SIZE, 0);
M6 I$ I3 k, a @5 i( C. Q6 I - if (length < 0)
$ s0 P2 K4 G! W4 v - {
3 x- d/ a* X6 x - printf("Server Recieve Data Failed!\n");
* T- s& u( q8 a l; e - break;
3 }2 X. U- x x+ [! z - }
, p+ M) {: F! g% D2 ?0 s - . {0 o. t: c* @+ F% X& i- e
- char file_name[FILE_NAME_MAX_SIZE + 1];
" t; O6 E2 G1 N. T - bzero(file_name, sizeof(file_name));* L, t2 g: [# j. i) s" ~. I5 L% L# }
- strncpy(file_name, buffer,
F# O/ O5 G! ^9 M5 t+ n - strlen(buffer) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));( W# b8 l3 J0 ~
- 9 l4 N& v6 x% |' u
- FILE *fp = fopen(file_name, "r");
& E% c5 T, c5 H1 ~- Y$ I - if (fp == NULL)5 ~2 t" k) ]) `: i* N
- {
) M, V6 I8 M! |2 k0 v+ _ P - printf("File:\t%s Not Found!\n", file_name);
& d3 K$ E9 J* O- e! \6 r4 `7 f0 H( Y - }6 ?! }, w: i! _2 {! C
- else
& l9 N. f$ B# i - {
1 l; O! j. G6 V9 X - bzero(buffer, BUFFER_SIZE);( h o |$ A( A0 L5 M
- int file_block_length = 0;, X8 H, u/ a4 t" s, a
- while( (file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
! v* F, j; r) R* q* D" T' q3 h - {$ D* i1 O' B3 o, F0 m
- printf("file_block_length = %d\n", file_block_length);. b& E' e- ]- \+ L6 w9 D
' e3 ^% G0 }) \1 @) V3 B- l, B- // 发送buffer中的字符串到new_server_socket,实际上就是发送给客户端
+ b" T: c6 V. c2 U6 g$ V0 a2 ?1 I# C - if (send(new_server_socket, buffer, file_block_length, 0) < 0)5 R! A& @4 I& t0 @) F
- {
" E/ t3 h7 V6 Z) v7 e/ r# D - printf("Send File:\t%s Failed!\n", file_name);
3 [5 M: i4 i- _* l - break;$ t8 v2 L( K8 |: A
- }7 ]! l6 n4 X- x5 [. D9 p' y
9 a- ?( @, r6 P4 R+ R7 W- bzero(buffer, sizeof(buffer));
4 D3 U! D: U1 u - }& n5 E9 }: I; }* q
- fclose(fp);
8 L% D& w3 \& P+ g( C# m( m - printf("File:\t%s Transfer Finished!\n", file_name);
4 C: t* X+ i# P* K3 b - }
/ L' L- }! F: e) \7 I& U - ) }: z0 g& B! p1 r
- close(new_server_socket);6 a6 {$ K: a* M# c l$ D
- }( _- N3 y" T3 i# _5 F! b5 ?
$ u1 V* K( W2 A4 \5 `- close(server_socket);8 I9 U& y+ l% K) O i/ n" s7 g
* P: P( Q: d5 x/ \) K$ n4 B" p3 i. f- return 0;
0 Q, w3 H6 J: y& B6 c. p - }7 G+ ?8 ], `+ H& [5 B
- " t6 [# |/ d% U8 R
复制代码
# N4 m4 {$ l( G) v' Y& [* r h' l) M% D) t4 c# i7 q
7 R; O7 ^2 m2 j5 U% c% Z, f+ l$ r
7 `" a7 m0 k3 z9 p- F5 w
| 欢迎光临 cncml手绘网 (http://www.cncml.com/) |
Powered by Discuz! X3.2 |