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