执行WEB服务前的准备工作

创建项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>

// 初始化网络并创建服务端的套接字
int startup(unsigned short* port){
return 0;
}

int main(void){
//httpd默认的端口是80,这里指定了8000端口,也可以使用其它端口
unsigned short port = 8000;

// 初始化网络,并使用指定端口来创建服务端的套接字
int server_sock = startup(&port);
printf("httpd running on port %d\n", port);

return(0);
}

网络通信初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//网络通信需要包含的头文件、需要加载的库文件
#include <winsock2.h>
#pragma comment (lib, "WS2_32.lib")

// 初始化网络并创建服务端的套接字
int startup(unsigned short* port) {
WSADATA wsaData; // 网络通信相关的版本等信息
int ret = WSAStartup( // WSAStartup 网络通信初始化,
MAKEWORD(1, 1), // 指定使用Windows Sockets规范的1.1版本
&wsaData); // 存储初始化后的版本等信息结果
if (ret) {
return -1;
}

return 0;
}

创建套接字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void error_die(const char* sc) {
perror(sc); //打印错误原因
exit(1);
}

// 初始化网络并创建服务端的套接字
int startup(unsigned short* port) {
int server_socket = socket(PF_INET, //套接字的类型(网络套接字、文件套接字,此处是前者)
SOCK_STREAM, //数据包的类型(数据流、数据报,此处是前者)
IPPROTO_TCP); //具体协议
if (server_socket == -1) { //打印错误提示,并结束程序
error_die("socket");
}
}

设置套接字属性–端口可复用

1
2
3
4
5
6
7
8
9
// 初始化网络并创建服务端的套接字
int startup(unsigned short* port) {
//设置端口可复用(端口复用)
int opt = 1;
ret = setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt));
if (ret == -1) {
error_die("setsockopt");
}
}

绑定套接字和网络地址

1
2
3
4
5
6
7
8
9
10
11
12
13
int startup(unsigned short* port) {
//配置服务器的网络地址
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(*port);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

//绑定套接字
if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
error_die("[bind]");
}
}

获取动态端口

1
2
3
4
5
6
7
8
9
10
11
int startup(unsigned short* port) {
// 动态分配端口
if (*port == 0) {
int namelen = sizeof(server_addr);
if (getsockname(server_socket, (struct sockaddr*)&server_addr, &namelen) <0) {
error_die("getsockname");
}
*port = ntohs(server_addr.sin_port);
}
return server_socket;
}

创建监听队列

1
2
3
4
5
6
7
int startup(unsigned short* port) {
//创建监听队列
if (listen(server_socket, 5) < 0) {
error_die("listen");
}
return server_socket;
}