//Server服务器端Server.cpp
1 // 定义控制台应用程序的入口点。
2 //
3
4 #include "stdafx.h"
5 #include <winsock2.h>
6 #include<iostream>
7 #pragma comment(lib,"ws2_32.lib")
8 using namespace std;
9 int main()
10 {
11 WORD wVersion;
12 WSADATA wsaData;
13 int er;
14 //1.初始化版本信息
15 wVersion = MAKEWORD(1, 1);
16 //加载套接字库
17 er = WSAStartup(wVersion, &wsaData);
18 if (er != 0)
19 {
20 return -1;
21 }
22 //检测套接字版本信息
23 if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
24 {
25 WSACleanup();
26 return -2;
27 }
28
29 //2.创建服务器端套接字
30 SOCKET sockSer = socket(AF_INET, SOCK_STREAM, 0);
31 /*
32 原型:SOCKET socket(int af,int type,int protocol)
33 参数:
34 af: 代表网络地址族,目前只有一种取值有效,即 AF_INET, 代表 internet 地址族。
35 type: 代表网络协议类型, SOCK_DGRAM 代表 UDP 协议, SOCK_STREAM 代表 TCP 协议。
36 protocol: 指定网络地址族特殊协议,目前无用,赋值0即可。
37 */
38 //3.绑定套接字
39 /*
40 nt bind( SOCKET s,const struct sockaddr FAR *name,int namelen);
41 参 数:
42 s:被绑定的套接字
43 name: 是一个sockaddr结构指针,该结构中包含了要绑定的地址和端口。
44 namelen:第二个参数name 的长度;
45 如果使用者不在意地址或端口的值,那么可以设定地址为 INADDR_ANY,及 Port 为 0。
46 对于多接口主机使用INADDR_ANY指定了一个通配地址,让该主机的任何一个IP地址都匹配。
47 */
48 SOCKADDR_IN addr_in;
49 addr_in.sin_family = AF_INET;//地址族
50 addr_in.sin_port = htons(7000);//端口
51 addr_in.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//IP
52 bind(sockSer, (sockaddr*)&addr_in, sizeof(addr_in));
53
54 //4.监听套接字,准备接受客户端发送的请求
55 /*
56 int listen(SOCKET s,int backlog );
57 参 数:
58 s:需要建立监听的 Socket;
59 backlog:最大连接个数;
60 */
61 listen(sockSer, 5);
62 //5.定义结构体,接受客户端的IP及端口号
63 /*
64 SOCKET accept(SCOKET s,struct sockaddr FAR *addr,int FAR *addrlen );
65 参数:
66 s: 监听套接字
67 addr:存放来连接的客户端的地址、端口信息;
68 addrlen:addr 的长度
69 */
70 SOCKADDR_IN client_addr;
71 int len = sizeof(client_addr);
72 while (true)
73 {
74 //等待客户的请求
75 cout << "服务器等待客户端请求.........." << endl;
76 SOCKET socClient = accept(sockSer, (SOCKADDR*)&client_addr, &len);
77 char sendBuf[1024];
78 //格式化字符串
79 sprintf(sendBuf, "%s C++学习教程", inet_ntoa(client_addr.sin_addr));
80 //6.发送数据
81 send(socClient, sendBuf, strlen(sendBuf) + 1, 0);
82 /*
83 int send(SOCKET s, const char FAR *buf, int len, int flags);
84 参数:
85 s: 是一个已建立连接的套接字。
86 buf:指向一个缓冲区,该缓冲区包含将要传递的数据。
87 len:缓冲区的长度。
88 flags:收发数据方式的标识,如果不需要特殊要求可以设置为0。
89
90 调用send函数向客户端发送数据,注意这个函数使用的套接字需要使用已建立连接的那个套接字,
91 而不是用于监听的那个套接字。
92 */
93 //7.接受数据
94 char recvBuf[1024];
95 recv(socClient, recvBuf, strlen(recvBuf) + 1, 0);
96 /*
97 int recv(SOCKET s,char FAR* buf, int len, int flags);
98 参数:
99 s:建立连接之后准备接收数据的那个套接字。
100 buf:指向缓冲区的指针,用来保存接收的数据。
101 len:缓冲区的长度。
102 flags:收发数据方式的标识,如果不需要特殊要求可以设置为0。
103 发送完数据之后还可以从客户端接收数据,这可以使用recv函数,应注意该函数的第一个参数也应该是建立连接之后的那个套接字,
104 并且定义一个字符数组recvBuf,用来保存接收的数据。
105 */
106 cout << "接受到的数据:" << recvBuf << endl;
107 //8.关闭套接字
108 closesocket(socClient);
109 }
110
111 return 0;
112 }