cncml手绘网
标题:
一个简单的C语言的socket服务器和客户端程序
[打印本页]
作者:
admin
时间:
2020-5-9 02:14
标题:
一个简单的C语言的socket服务器和客户端程序
程序很简单,windows环境下的,客户端和服务器程序都在本机运行,在客户端输入发送给服务器的字符串,服务器收到字符串后会打印出来,同时与"abc"比较,与"abc"相同就会返给客户端,输入的是正确的,不同会告诉客户端输入时错误的。
1 U, {8 f+ y& W6 l8 N4 [: }
客户端程序:client.cpp
3 g: I! m* m- \( K' n7 p7 @
#include <winsock2.h>
# x8 ^& W: m' U" d4 Y9 u6 b, i
#include <stdio.h>
/ V* {% o) n0 K( ^" P1 l. ]- z
#include <stdlib.h>
8 H3 r* S8 e& y5 G" P7 m% A
, E; S! p% \/ x0 a) H- G
#define DEFAULT_PORT 5150
k8 @/ ]8 p6 d0 _) v) l3 V( u
#define DEFAULT_BUFFER 2048
$ f( e: Q* @) d/ J9 Z, X$ t0 ^
. B. B, r+ e, V4 Q0 q- T' |' V
char szServer[128],
# R! l7 I- p2 [4 ~9 s5 L
szMessage[1024];
! V1 i# s8 p8 T* n, o7 m6 X, G2 Q- D: [$ n
int iPort = DEFAULT_PORT;
9 f# \, [4 f3 q( l7 G
1 v( c _) H# P: p# R
int main()
% B; b3 e/ f1 {3 j
{
6 L- K( ~8 E5 | d$ {5 e4 z
WSADATA wsd;
: y/ p# |7 o# `& {+ k+ y" E$ b. a
SOCKET sClient;
1 b( p" ?) y* v
char szBuffer[DEFAULT_BUFFER];
& z S8 G5 u) ~
int ret;
: f! F, `$ k' z5 i) O
struct sockaddr_in server;
1 @, t/ T! N1 {6 }9 _1 U( C
struct hostent *host = NULL;
& _5 Z8 ~% h7 S" V. d+ ^3 y
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
' z- i8 _0 f5 h3 |. J
{
! o8 A* \4 i* a. @
printf("Failed to load Winsock library!\n");
4 k/ v0 y6 p9 `% t7 k+ k
return 1;
+ j' ?+ A! H/ ?1 J% ]
}
$ p% ~: a+ i# @ q* `
printf("Enter a string to send to server:\n");
- F. @( w* g( n2 J6 c" Q# @
gets(szMessage);
4 D+ n( `6 c- |" f0 i
// Create the socket, and attempt to connect to the server
2 J2 I- b. t2 G7 D: b. M7 a5 |/ T. X
sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
. f0 b) M' S8 P) [% W
if (sClient == INVALID_SOCKET)
4 y2 w) a0 O! m
{
_4 T/ J9 x0 I! u
printf("socket() failed: %d\n", WSAGetLastError());
% t" }% M( t! Y3 g, u% R
return 1;
/ x, x& ]5 W: K4 e& z
}
; O4 M* `5 E0 @) t
server.sin_family = AF_INET;
8 }# G' S3 f T; m4 R, B' g
server.sin_port = htons(iPort);
* i: w8 R% z; ^% |
server.sin_addr.s_addr = inet_addr("127.0.0.1");
6 e: |! s* O( v' Q) U/ b, z
9 [6 S+ ]9 I( C- p, ?+ \
if (connect(sClient, (struct sockaddr *)&server,
' G2 J% a; g$ Y
sizeof(server)) == SOCKET_ERROR)
K6 C* B; k/ D" C1 r8 f
{
- p2 K" t/ g" O: Q4 E- W; {" b" }1 A
printf("connect() failed: %d\n", WSAGetLastError());
. Z7 L7 j3 J1 c1 C1 x8 Z" [
return 1;
' H: j. W1 C- H% ^ W* W
}
/ m+ |2 j! A& E: I: M
// Send and receive data
* \$ d) v+ r, }4 t( K. @" W
ret = send(sClient, szMessage, strlen(szMessage), 0);
7 H- i- I) y' r3 f) Y% g
if (ret == SOCKET_ERROR)
6 n" q' N2 X3 x! T2 ?
{
% Z) @7 e, @9 k R5 J
printf("send() failed: %d\n", WSAGetLastError());
4 B- m2 x) [, W" F5 O
}
4 k7 f9 _4 U0 g, }, |
else{
- t: J4 z7 ^4 v$ d4 N8 X
printf("Send '%s' \n", szMessage);
- ]" n! n [3 n `0 q& E2 o' a
ret = recv(sClient, szBuffer, DEFAULT_BUFFER, 0);
- Y3 W& x$ j( O T+ N
if (ret == SOCKET_ERROR){
2 T! ?# F4 t+ V' v9 I' l! z
printf("recv() failed: %d\n", WSAGetLastError());
) V/ B+ N" f, j9 K& f- ?3 D
}
; M" ]# d4 N7 B. n" O$ Z# u
else{
, |8 D$ \6 {4 w* N+ X. b1 Z
szBuffer[ret] = '\0';
1 F" [9 z. ~4 H/ Y$ {
printf("RECV: '%s'\n",szBuffer);
1 M3 e/ { w. e8 v* g' D& T! Q
}
1 T s, ~$ o5 P" J2 H) U, m, E
}
! o5 R* T8 E0 ^( z* ~5 K
closesocket(sClient);
! |' l; C" _0 U4 S
2 Q$ J) B% v( q2 ~, s
WSACleanup();
8 k7 H4 o- P# ^" u' v" w1 C$ S2 I
return 0;
5 A# i0 ^# e0 a3 N
}
复制代码
服务器程序:server.cpp
5 O2 r, b" a0 }" A6 }, p) m% f
#include <winsock2.h>
' _# Q- F& H' J+ m2 P2 M% v
#include <stdio.h>
1 v% m9 g' Q& }8 R6 k" S
#include <stdlib.h>
5 Z; O$ B9 m# I+ J& S' [2 h/ s
% m J1 s4 d, D! ^, l( Z$ Y1 K
#define DEFAULT_PORT 5150
' F4 s( k7 n. C$ E) p9 q+ p% H9 n
#define DEFAULT_BUFFER 4096
) Y' `* M# ?2 u3 H
) K2 o- p/ n/ D4 n' U# @
int iPort = DEFAULT_PORT;
2 S( P( y( i' f( I6 R
char szAddress[128];
+ \1 s0 e2 H5 S
0 O) ~7 W1 M- M) V4 Q7 J
DWORD WINAPI ClientThread(LPVOID lpParam)
/ I$ r' P$ |" C4 `8 h; u
{
N) O3 S/ w$ D8 ~. c V1 m2 S
SOCKET sock=(SOCKET)lpParam;
0 [6 Q: b: B; z6 N; j- ~
char szBuff[DEFAULT_BUFFER];
' h/ O {/ K% ?+ ~1 ]; |1 m
int ret;
* m L" Z) f& D+ ]3 a
4 B+ \$ a8 o& {9 N6 `" B$ m$ ?% O1 s, a
while(1)
, S( v. e9 S; M. A; v
{
; T0 ?+ a9 _% ]+ u
ret = recv(sock, szBuff, DEFAULT_BUFFER, 0);
# F9 \5 }7 B" U" A% m8 @6 n
if (ret == 0)
/ U; y) \6 K; k
break;
5 H* o2 H; x; v' G: o& [: N6 |. N$ Z
else if (ret == SOCKET_ERROR)
' D8 ?0 X) {: ?$ L. i0 h% H( j
{
- g% e7 n- w [4 F; [# v
printf("recv() failed: %d\n", WSAGetLastError());
+ {" U$ ~9 M8 G# z% B* L( F" ]
break;
3 Z7 j: B* ]% w, `) p' ^1 c) M. `
}
( B* L5 \+ z: J8 T/ U" ^1 ?
szBuff[ret] = '\0';
* i( I$ V, A m! e# E& z2 x
printf("RECV: '%s'\n", szBuff);
4 R5 m( k9 a- N
if(strcmp(szBuff,"abc")==0){
7 W- c6 q! ^- a0 l) i
memcpy(szBuff,"Send the correct string!",25);
! u' v) }% g- ], i
}
* D" o% H6 J% ]. A& y( I
else{
6 {) ]! f9 W% Z. [
memcpy(szBuff,"Send the wrong string!",23);
$ }" t) P5 a, ?
}
- u3 X2 |) R P! }$ ^
ret = send(sock, szBuff, strlen(szBuff), 0);
' v% f2 ]" ?& x
if (ret == SOCKET_ERROR){
, K! `% W2 Z2 X
printf("send() failed: %d\n", WSAGetLastError());
- a* M" Z9 }2 v- d( b) m2 U8 o
}
* L! \% s' P; y' @
}
! d* D- c+ k/ m8 g+ z/ r
return 0;
, V+ \. u! _" F5 L: N) b; O
}
' D3 p3 M! j" f* a, P
7 |( N4 L. K* q# o% f1 {# p5 D
int main()
3 _7 n, k5 d0 `& I& Z" S
{
+ T7 x+ T" n9 g1 ]
WSADATA wsd;
( ]# v m2 W0 w, M
SOCKET sListen,
! |# f/ o7 c, e
sClient;
. c5 E6 j) q* m- S
int iAddrSize;
: r" y0 B* |. s+ A' K
HANDLE hThread;
% S$ n j7 I2 s* Q' D/ e
DWORD dwThreadId;
2 W. q5 Y: V6 S3 f" Z! \9 f+ ~
struct sockaddr_in local,
a- y# I8 y! [- e
client;
; i' i- g6 }5 |6 M/ c3 v% k! b1 o
& z+ z: S2 H; Y9 V3 j) i/ [
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
9 C! G* B& v/ V4 [4 e+ m; B
{
$ [6 ], N7 O: S$ Z
printf("Failed to load Winsock!\n");
5 S2 B& D- k5 _7 [/ L' i8 A$ {
return 1;
; z9 h/ ?8 A, i2 @* K5 X* a6 H- F
}
) I S& B8 P7 }/ Y0 H
// Create our listening socket
1 X% I3 f6 G2 _+ s _% |$ `4 V1 N: S
sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
# s7 n! i3 a/ A+ ^( k. u% x H
if (sListen == SOCKET_ERROR)
; _- Q/ z, U* U4 P8 z
{
4 w0 [! g y G& h
printf("socket() failed: %d\n", WSAGetLastError());
( V( C" l9 G% u; h
return 1;
6 |# d3 Y }9 ]' D) v- z; f2 _
}
8 H# _* b0 ?# c, ~ \. o# z# p
local.sin_addr.s_addr = htonl(INADDR_ANY);
; W$ F1 y( z P! ?% H
local.sin_family = AF_INET;
3 [; \2 L8 y; n9 c
local.sin_port = htons(iPort);
, [6 q3 u g/ T0 p: i- ?
& v- {( j7 g$ e, x+ _
if (bind(sListen, (struct sockaddr *)&local,
. Q8 a+ f; \ P/ ^% p
sizeof(local)) == SOCKET_ERROR)
) B0 o/ m( u) K9 i& p
{
) a* p7 Q5 ~0 \6 n( y6 J
printf("bind() failed: %d\n", WSAGetLastError());
. O3 {+ l; P: `$ ^. q2 R
return 1;
- m2 w3 l1 W2 r: R+ }
}
K8 ]6 @* ]2 X; @
listen(sListen, 8);
8 }. ~# b& b: h, q- x: p
// In a continous loop, wait for incoming clients. Once one
: c6 E: ^! B( h
// is detected, create a thread and pass the handle off to it.
\, I+ C( m' Z" k" C+ R- s
while (1)
1 w" H Q+ G9 \% |
{
; M% ]3 Q1 t* s
iAddrSize = sizeof(client);
" b4 _* v* b( O% y
sClient = accept(sListen, (struct sockaddr *)&client,
/ ?' d _2 |- [* ~/ I, y$ |
&iAddrSize);
" Y& I, W( j$ [2 s. e5 M& r @
if (sClient == INVALID_SOCKET)
# B& {( p* ?& I$ v
{
/ C3 A" T7 r% X( h- u
printf("accept() failed: %d\n", WSAGetLastError());
4 m3 g. g5 l6 }9 j1 N
break;
* u" _' N3 H3 s
}
- N3 y5 J) h: I* D* R% O, x
printf("Accepted client: %s:%d\n",
4 `5 ]; _( H$ f& n9 m$ u7 n) f2 y
inet_ntoa(client.sin_addr), ntohs(client.sin_port));
/ |9 O9 O" v0 n2 {# I& u
1 E5 D: M( G. D# F0 ~
hThread = CreateThread(NULL, 0, ClientThread,
' Y5 s/ A k8 D, R% k$ A
(LPVOID)sClient, 0, &dwThreadId);
; d# X1 c: F$ T6 K# u4 I
if (hThread == NULL)
6 B5 D+ Q9 `+ {* i5 H# u y2 q/ E
{
$ D& {- \+ y( w7 K
printf("CreateThread() failed: %d\n", GetLastError());
1 }. T0 l8 B$ E5 p/ e( {0 v
break;
* }% p7 F z+ l$ I. D% U+ P' B
}
0 T) e$ n# i2 J
CloseHandle(hThread);
( ]1 C7 K8 h# B& T
}
8 G0 ]8 W* z$ H) m. U: \
closesocket(sListen);
! L' o2 k& v. S! }- ^# _( @
( J& _+ d2 d3 n5 J& g
WSACleanup();
, e% v, V* q2 T& f& T
return 0;
+ B! d. ?8 b0 s, l$ _
}
复制代码
; _- l n( G7 E/ M5 _* I- A" n
2 u, h' S6 s# g2 Y: E8 n6 Q. O
- Y: W6 v) H2 l* A, ~% \& D; u) y
0 d8 z1 S% C- X0 O L& ?
& u. k, ~, h6 M/ b2 K
作者:
admin
时间:
2020-5-9 02:16
作为服务器,你要绑定【bind】到本地的IP地址上进行监听【listen】,但是你的机器上可能有多块网卡,也就有多个IP地址,这时候你要选择绑定在哪个IP上面,如果指定为INADDR_ANY,那么系统将绑定默认的网卡【即IP地址】。
: D; u5 s. M/ n+ Q2 z9 K
# J7 C9 M, ^- S: [: N
作为客户端,你要连接【connect】到远端的服务器,也是要指定远端服务器的(ip, port)对。
4 \+ u' q: ]/ ], Y, ?1 c; s
当然,在这种情况下,不可能将IP地址指定为INADDR_ANY,系统会疯掉的。
3 D% r6 M' i" n
2 [% I! e0 K1 l0 }% r" U* L9 |
Server:
6 `6 I; c$ H1 h4 X1 ^/ s
#include <winsock2.h>
% [6 O+ f/ g; `) ^$ R
#pragma comment(lib, "WS2_32.lib")
w+ W( V3 ^4 j. ?( O
s2 S4 N! u% ?/ d" x2 M( N
#include <stdio.h>
, W0 H1 _- [3 k' ?4 f! B( L
void main()
. ]( ^" h, b b
{
6 \! r5 T/ _! K, p& |: }
WORD wVersionRequested;//版本号
8 K5 J+ B) K1 x! j1 E8 J" t7 v
WSADATA wsaData;
5 j- j" k H1 K: Z2 e
int err;
2 E9 Q7 }$ A" Q) ?" Y; ~ A4 Y
: I2 K& `% q' Z% T% [# U$ h, h: ?
wVersionRequested = MAKEWORD(2, 2);//2.2版本的套接字
8 k0 _% s1 b8 q: X* }+ v! b7 m
//加载套接字库,如果失败返回
/ V7 R: X3 a9 D0 l
err = WSAStartup(wVersionRequested, &wsaData);
, Y0 e& s$ U5 p
if (err != 0)
% E: h6 Z& A7 a3 |! I4 r
{
5 z6 Q _: S4 S- m
return;
/ K2 P; u0 h/ C5 ]( N# I5 _
}
7 \! |5 ?0 z# P6 `8 N
% j9 b# `) e/ t; }3 h2 V; z
//判断高低字节是不是2,如果不是2.2的版本则退出
/ I; R, @5 { q) ?0 W3 ]
if (LOBYTE(wsaData.wVersion) != 2 ||
1 u/ v+ S* X& ?' k" [$ J
! x% A8 f% s( j. m+ R5 }
HIBYTE(wsaData.wVersion) != 2)
' a* i/ P2 @) d \+ g. O
1 }( q0 K- D5 j( |2 ?; Z! _( K" }+ O* L
{
% O/ I+ c$ _. \% ^+ R9 ^
return;
6 u T6 s$ B! P$ ~
}
+ K/ n0 l. o7 U6 \4 W
3 M& g+ d% q$ L1 u% V) J
//创建流式套接字,基于TCP(SOCK_STREAM)
: j5 l j: m! U% |
4 F. V* Y7 v3 K7 }9 R
SOCKET socSrv = socket(AF_INET, SOCK_STREAM, 0);
% r7 {( d0 ?% x* m) V0 E: c
$ N9 V& M) }& t$ L3 U
//Socket地址结构体的创建
; _/ V4 \# o4 \; s( M
: r$ P! x+ t' @! T( N
SOCKADDR_IN addrSrv;
) B" b- K# b; s0 \
9 L) k2 u; n( X4 f7 d# p
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//转换Unsigned long型为网络字节序格
# S; i& U) }& T9 X0 V
addrSrv.sin_family = AF_INET;//指定地址簇
2 a! c1 c* V% r. B' o) j
addrSrv.sin_port = htons(6000);
8 y \, F" j+ C
//指定端口号,除sin_family参数外,其它参数都是网络字节序,因此需要转换
. x" [, q( Q" R+ H
0 X, m" g& E7 j3 P& Y
//将套接字绑定到一个端口号和本地地址上
9 ]0 f, H5 ?$ t0 M
bind(socSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));//必须用sizeof,strlen不行
5 |! f e7 ^/ d3 T1 ` g
0 p2 U9 M4 L+ J: O7 l
listen(socSrv, 5);
2 u0 O. ?. ], c" b5 N- i C0 u
2 v/ | ~9 T. }3 D# s3 p$ Y
SOCKADDR_IN addrClient;//字义用来接收客户端Socket的结构体
* S z) O5 C8 {/ \' e6 }
; H p1 c7 q4 i+ |
int len = sizeof(SOCKADDR);//初始化参数,这个参数必须进行初始化,sizeof
7 V4 Y8 }* p& v" U3 }2 _8 W3 d
/ R k# S5 K3 ?. S: |
//循环等待接受客户端发送请求
! q. k0 i2 Z* C: j
3 u. d- J5 ~% v7 @
while (1)
+ G# [4 o- Z2 N
{
. \- C- l/ l" l m
//等待客户请求到来;当请求到来后,接受连接请求,
* B% J, N9 ]% o2 O# t
% P4 C5 `/ G* Q6 w2 t- {3 j
//返回一个新的对应于此次连接的套接字(accept)。
T( Y- C) M5 S5 {% l) U
//此时程序在此发生阻塞
4 A% S# q" y) T! o9 |5 u
2 G+ p; K' I; ?" N6 q0 ?2 ?0 W
SOCKET sockConn = accept(socSrv, (SOCKADDR*)&addrClient, &len);
2 Y4 S% x& Q+ O1 h
! d: s, U4 m% Q, @" O
char sendBuf[100];
. X3 F9 [7 T* C# w8 N1 J
& i. l2 m" W$ g# N7 ^% x( t. T
sprintf(sendBuf, "Welcome %s to JoyChou",
$ W2 b! F- J9 N+ I: r5 i
( I# V! {/ ^4 N. D' i& Q
inet_ntoa(addrClient.sin_addr));//格式化输出
A V1 n+ }9 K' `2 G- R
) \* D; X/ j2 |& h+ C; \7 ^- t5 A
//用返回的套接字和客户端进行通信
) \ F& j* g' s! d
5 h; K' v3 N+ b+ @2 `
send(sockConn, sendBuf, strlen(sendBuf)+1, 0);//多发送一个字节
1 z: M% o& h+ g( }9 |
+ b: W$ O) P5 J9 ~# Y/ N4 v
//接收数据
2 s) J8 U' N! `+ g' Z' y
2 j/ i K, ^. k( z$ Y& ~1 f
char recvBuf[100];
5 H$ N1 ^/ P5 Z- V7 `! z4 ^
. D/ s* k: Z% {- \; |
recv(sockConn, recvBuf, 100, 0);
" v+ v& B) R. C' a
# S3 E! K! V$ a8 U. @6 d& s2 t0 G
printf("%s\n", recvBuf);
) t& S- p; z! g" w: M, x( F6 g6 q
closesocket(sockConn);
: P( g$ ]' F! v5 ^- t5 F/ Q/ @. n
6 w, c5 `5 B, L# I! Z
}
& L8 f$ _" b7 O, u# P8 V0 x6 R( Z {" F
}
+ r" @2 W/ u. D$ }
6 _* s1 W" h5 u1 C5 u7 ~1 f+ V6 a
/ I9 ^+ U% ?( R8 u1 \
Client:
4 {) w, u* h$ k J! U
4 N: Q* X V" N: J: k/ [2 i6 R
#include <winsock2.H>
' r* A' ~ C" I, K
#pragma comment(lib, "Ws2_32.lib")
! g5 I; Y4 I, P! D" V) ]
#include <stdio.h>
2 o% F: r3 A6 L! S2 e
#include <string.h>
! g; Z# D& u1 A. |" e
k, H9 E. n6 F
void main()
. e3 _. K9 X1 G/ r5 w( F
{
+ e! Y' V5 `5 r1 P! E
WORD wVersionRequested;
8 s2 T, ]" M" h2 V% S
WSADATA wsaData;
2 @; J3 ]" g/ A6 m# Y3 Z0 `
int err;
; N k5 @# |4 U L0 U( X# w
z. C2 z4 i6 J# E, `! r, F
wVersionRequested = MAKEWORD( 2, 2 );
4 A# K6 I% P0 Y
2 o# d+ h5 e' r
err = WSAStartup( wVersionRequested, &wsaData );
9 t1 i7 c% @) F3 C+ i
if ( err != 0 ) {
. C8 K8 U. A2 u- }
/ ]( O- n* _9 e4 x9 @ }( O
return;
0 S& J5 X4 V7 Y& Z. f5 g" R
}
, I- U4 [* A2 ~: B% e- j0 e2 E: I
; e& s; _5 E8 y' k/ M" M, L3 E
, e( r2 z5 _+ R7 Z [) \
if ( LOBYTE( wsaData.wVersion ) != 2 ||
# @5 R3 s# w$ X( r5 [
HIBYTE( wsaData.wVersion ) != 2 )
" i3 ]3 V1 S. E4 `: T
{
- B& q2 S1 M! o1 ?* C
" I1 P0 H7 ~0 d/ a7 v# F7 u; G* l
WSACleanup( );
+ [# f8 c, w0 c4 {
return;
7 m0 e8 O9 F% b' Z
}
0 Q/ N* n5 f Q" n9 D" t7 V
SOCKET socketClient = socket(AF_INET, SOCK_STREAM, 0);
a3 m6 Q g7 h0 z
SOCKADDR_IN addrSrv;
* Q& Y1 J9 G$ ~! C+ W( x
addrSrv.sin_family = AF_INET;
" M' b! D3 B2 D! A. t7 R
addrSrv.sin_port = htons(6000);
9 v6 o; _5 r7 ]5 Q. h0 ^; b
addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.1.101");//服务器端的IP地址
- ]2 c( f2 B! E( q9 R, T
9 z/ c( [) f$ z; P
connect(socketClient, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));
( j3 D0 G! D7 O1 y* B" y
char recvBuf[256];
* S" w" k% J7 L; w
char sendBuf[] = "This is Joychou";
" X% b4 l( m+ d. g' V
recv(socketClient, recvBuf, 256, 0);
6 z; t1 v1 X" f+ l$ F# N9 B
printf("%s\n", recvBuf);
, R2 @$ C6 t( w5 c+ [% ~
send(socketClient, sendBuf, strlen(sendBuf) + 1, 0);
) g& _# {8 ]* S2 b* m X3 n
closesocket(socketClient);
# y5 M# `) z( o
WSACleanup();
) ^4 ^- `2 _3 T$ z" H6 f5 ^9 T
3 f4 k: \% L: v- ^& T" ?, r/ y3 Q
}
复制代码
. i6 t' d9 G. R; H! j& Q% e' u
) Q. d# B* c( R; C; M
欢迎光临 cncml手绘网 (http://bbs.cncml.com/)
Powered by Discuz! X3.2