[toc]

用C语言在windows中使用http协议发送文本消息

1. 用C语言在windows中使用http协议创建一个服务端程序,输出hello,world

  1. WinServer.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//WinServer.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

#define PORT 8080
#define BUFFER_SIZE 1024

void handle_request(SOCKET client_socket) {
char buffer[BUFFER_SIZE];
int bytes_received = recv(client_socket, buffer, sizeof(buffer) - 1, 0);
if (bytes_received > 0) {
buffer[bytes_received] = '\0'; // 添加字符串结束符
printf("Received request:\n%s\n", buffer);

// 简单的HTTP响应
const char* response_header = "HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Connection: close\r\n"
"\r\n";
const char* response_body = "Hello, World!";

// 发送响应
send(client_socket, response_header, strlen(response_header), 0);
send(client_socket, response_body, strlen(response_body), 0);
}

// 关闭客户端套接字
closesocket(client_socket);
}

int main() {
WSADATA wsaData;
SOCKET server_socket, client_socket;
struct sockaddr_in server, client;
int client_len = sizeof(client);

// 初始化WinSock
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("Failed to initialize WinSock. Error Code: %d\n", WSAGetLastError());
return 1;
}

// 创建套接字
server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (server_socket == INVALID_SOCKET) {
printf("Could not create socket. Error Code: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}

// 设置服务器信息
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY; // 监听所有IP
server.sin_port = htons(PORT);

// 绑定套接字
if (bind(server_socket, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) {
printf("Bind failed. Error Code: %d\n", WSAGetLastError());
closesocket(server_socket);
WSACleanup();
return 1;
}

// 开始监听
listen(server_socket, SOMAXCONN);
printf("Server listening on port %d...\n", PORT);

// 主循环,接受客户端连接
while (1) {
client_socket = accept(server_socket, (struct sockaddr*)&client, &client_len);
if (client_socket == INVALID_SOCKET) {
printf("Accept failed. Error Code: %d\n", WSAGetLastError());
continue;
}

// 处理请求
handle_request(client_socket);
}

// 关闭服务器套接字
closesocket(server_socket);
WSACleanup();
return 0;
}

  1. 使用浏览器访问127.0.0.1:8080

  2. 结果

2. 用C语言在windows中使用http协议创建一个服务端程序,根据路径返回不同的响应

  1. WinServer.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//WinServer.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable:4996)

#define PORT 8080
#define BUFFER_SIZE 1024

void handle_request(SOCKET client_socket) {
char buffer[BUFFER_SIZE];
int bytes_received = recv(client_socket, buffer, sizeof(buffer) - 1, 0);
if (bytes_received > 0) {
buffer[bytes_received] = '\0'; // 添加字符串结束符
printf("Received request:\n%s\n", buffer);

// 解析请求行
char method[16], path[256], version[16];
sscanf(buffer, "%s %s %s", method, path, version);

// 响应内容
const char* response_header;
const char* response_body;

// 根据路径返回不同的响应
if (strcmp(path, "/") == 0) {
response_header = "HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Connection: close\r\n"
"\r\n";
response_body = "Welcome to the home page!";
}
else if (strcmp(path, "/hello") == 0) {
response_header = "HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Connection: close\r\n"
"\r\n";
response_body = "Hello, World!";
}
else {
response_header = "HTTP/1.1 404 Not Found\r\n"
"Content-Type: text/plain\r\n"
"Connection: close\r\n"
"\r\n";
response_body = "404 Not Found";
}

// 发送响应
send(client_socket, response_header, strlen(response_header), 0);
send(client_socket, response_body, strlen(response_body), 0);
}

// 关闭客户端套接字
closesocket(client_socket);
}

int main() {
WSADATA wsaData;
SOCKET server_socket, client_socket;
struct sockaddr_in server, client;
int client_len = sizeof(client);

// 初始化WinSock
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("Failed to initialize WinSock. Error Code: %d\n", WSAGetLastError());
return 1;
}

// 创建套接字
server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (server_socket == INVALID_SOCKET) {
printf("Could not create socket. Error Code: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}

// 设置服务器信息
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY; // 监听所有IP
server.sin_port = htons(PORT);

// 绑定套接字
if (bind(server_socket, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) {
printf("Bind failed. Error Code: %d\n", WSAGetLastError());
closesocket(server_socket);
WSACleanup();
return 1;
}

// 开始监听
listen(server_socket, SOMAXCONN);
printf("Server listening on port %d...\n", PORT);

// 主循环,接受客户端连接
while (1) {
client_socket = accept(server_socket, (struct sockaddr*)&client, &client_len);
if (client_socket == INVALID_SOCKET) {
printf("Accept failed. Error Code: %d\n", WSAGetLastError());
continue;
}

// 处理请求
handle_request(client_socket);
}

// 关闭服务器套接字
closesocket(server_socket);
WSACleanup();
return 0;
}

  1. 使用浏览器访问会不同路径会显示不同结果
    • 127.0.0.1:8080显示Welcome to the home page!
    • http://127.0.0.1:8080/hello显示Hello, World!
    • 访问其他路径显示404 Not Found
  2. 结果

3. 用C语言在windows中使用http协议创建一个客户端程序访问服务器根路径

  1. 编写WinClient.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//WinClient.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable:4996)

#define SERVER "127.0.0.1" // 服务器地址
#define PORT 8080 // 服务器端口
#define BUFFER_SIZE 1024

int main() {
WSADATA wsaData;
SOCKET sock;
struct sockaddr_in server;
char request[BUFFER_SIZE], response[BUFFER_SIZE];
int bytes_received;

// 初始化WinSock
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("Failed to initialize WinSock. Error Code: %d\n", WSAGetLastError());
return 1;
}

// 创建套接字
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET) {
printf("Could not create socket. Error Code: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}

// 设置服务器信息
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(SERVER);
server.sin_port = htons(PORT);

// 连接到服务器
if (connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0) {
printf("Connect failed. Error Code: %d\n", WSAGetLastError());
closesocket(sock);
WSACleanup();
return 1;
}

// 构建HTTP GET请求
sprintf(request, "GET / HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", SERVER);

// 发送请求
send(sock, request, strlen(request), 0);

// 接收响应
while ((bytes_received = recv(sock, response, sizeof(response) - 1, 0)) > 0) {
response[bytes_received] = '\0'; // 添加字符串结束符
printf("%s", response); // 打印响应
}

// 关闭套接字
closesocket(sock);
WSACleanup();
return 0;
}

  1. 运行WInServer.exe后再运行WinClient.exe

  2. 运行结果

4. 用C语言在windows中使用http协议创建一个客户端程序访问服务器路径/hello

  1. WinClient.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//WinClient.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable:4996)

#define SERVER "127.0.0.1" // 服务器地址
#define PORT 8080 // 服务器端口
#define BUFFER_SIZE 1024

int main() {
WSADATA wsaData;
SOCKET sock;
struct sockaddr_in server;
char request[BUFFER_SIZE], response[BUFFER_SIZE];
int bytes_received;

// 初始化WinSock
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("Failed to initialize WinSock. Error Code: %d\n", WSAGetLastError());
return 1;
}

// 创建套接字
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET) {
printf("Could not create socket. Error Code: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}

// 设置服务器信息
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(SERVER);
server.sin_port = htons(PORT);

// 连接到服务器
if (connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0) {
printf("Connect failed. Error Code: %d\n", WSAGetLastError());
closesocket(sock);
WSACleanup();
return 1;
}

// 构建HTTP GET请求,连接到"/hello"
sprintf(request, "GET /hello HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", SERVER);

// 发送请求
send(sock, request, strlen(request), 0);

// 接收响应
while ((bytes_received = recv(sock, response, sizeof(response) - 1, 0)) > 0) {
response[bytes_received] = '\0'; // 添加字符串结束符
printf("%s", response); // 打印响应
}

// 关闭套接字
closesocket(sock);
WSACleanup();
return 0;
}

  1. 运行WInServer.exe后再运行WinClient.exe
  2. 运行结果

5. 使用POST请求而非GET请求

GET与POST用途

  • GET请求:通常用于获取资源或数据(如网页、图片等)。
  • POST请求:通常用于提交数据(如表单提交、文件上传等),并可能导致服务器状态的改变。
  1. WinClient.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
////WinClient.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable:4996)

#define SERVER "127.0.0.1" // 服务器地址
#define PORT 8080 // 服务器端口
#define BUFFER_SIZE 1024

int main() {
WSADATA wsaData;
SOCKET sock;
struct sockaddr_in server;
char request[BUFFER_SIZE], response[BUFFER_SIZE];
int bytes_received;

// 初始化WinSock
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("Failed to initialize WinSock. Error Code: %d\n", WSAGetLastError());
return 1;
}

// 创建套接字
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET) {
printf("Could not create socket. Error Code: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}

// 设置服务器信息
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(SERVER);
server.sin_port = htons(PORT);

// 连接到服务器
if (connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0) {
printf("Connect failed. Error Code: %d\n", WSAGetLastError());
closesocket(sock);
WSACleanup();
return 1;
}

// 构建HTTP POST请求
const char* post_data = "param1=value1&param2=value2"; // 要发送的数据
sprintf(request, "POST /hello HTTP/1.1\r\n"
"Host: %s\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n"
"Content-Length: %lu\r\n"
"Connection: close\r\n\r\n"
"%s", SERVER, strlen(post_data), post_data);

// 发送请求
send(sock, request, strlen(request), 0);

// 接收响应
while ((bytes_received = recv(sock, response, sizeof(response) - 1, 0)) > 0) {
response[bytes_received] = '\0'; // 添加字符串结束符
printf("%s", response); // 打印响应
}

// 关闭套接字
closesocket(sock);
WSACleanup();
return 0;
}

  1. 运行WInServer.exe后再运行WinClient.exe

  2. 运行结果

6.使用http协议可以让两个程序互相发送文本消息

  1. Winserver.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable:4996)

#define PORT 8080
#define BUFFER_SIZE 1024

void handle_request(SOCKET client_socket) {
char buffer[BUFFER_SIZE];
int bytes_received = recv(client_socket, buffer, sizeof(buffer) - 1, 0);
if (bytes_received > 0) {
buffer[bytes_received] = '\0'; // 添加字符串结束符
printf("Received request:\n%s\n", buffer);

// 解析请求体
char* body = strstr(buffer, "\r\n\r\n");
if (body != NULL) {
body += 4; // 跳过"\r\n\r\n"
printf("Received message: %s\n", body);
}

// 响应内容
const char* response_header = "HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Connection: close\r\n\r\n";
const char* response_body = "Message received!";

// 发送响应
send(client_socket, response_header, strlen(response_header), 0);
send(client_socket, response_body, strlen(response_body), 0);
}

// 关闭客户端套接字
closesocket(client_socket);
}

int main() {
WSADATA wsaData;
SOCKET server_socket, client_socket;
struct sockaddr_in server, client;
int client_len = sizeof(client);

// 初始化WinSock
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("Failed to initialize WinSock. Error Code: %d\n", WSAGetLastError());
return 1;
}

// 创建套接字
server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (server_socket == INVALID_SOCKET) {
printf("Could not create socket. Error Code: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}

// 设置服务器信息
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY; // 监听所有IP
server.sin_port = htons(PORT);

// 绑定套接字
if (bind(server_socket, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) {
printf("Bind failed. Error Code: %d\n", WSAGetLastError());
closesocket(server_socket);
WSACleanup();
return 1;
}

// 开始监听
listen(server_socket, SOMAXCONN);
printf("Server listening on port %d...\n", PORT);

// 主循环,接受客户端连接
while (1) {
client_socket = accept(server_socket, (struct sockaddr*)&client, &client_len);
if (client_socket == INVALID_SOCKET) {
printf("Accept failed. Error Code: %d\n", WSAGetLastError());
continue;
}

// 处理请求
handle_request(client_socket);
}

// 关闭服务器套接字
closesocket(server_socket);
WSACleanup();
return 0;
}

  1. WinClient.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <conio.h>

#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable:4996)

#define SERVER "127.0.0.1" // 服务器地址
#define PORT 8080 // 服务器端口
#define BUFFER_SIZE 1024

int main() {
WSADATA wsaData;
SOCKET sock;
struct sockaddr_in server;
char request[BUFFER_SIZE], response[BUFFER_SIZE];
int bytes_received;

// 初始化WinSock
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("Failed to initialize WinSock. Error Code: %d\n", WSAGetLastError());
return 1;
}

// 创建套接字
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET) {
printf("Could not create socket. Error Code: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}

// 设置服务器信息
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(SERVER);
server.sin_port = htons(PORT);

// 连接到服务器
if (connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0) {
printf("Connect failed. Error Code: %d\n", WSAGetLastError());
closesocket(sock);
WSACleanup();
return 1;
}

// 构建HTTP POST请求
const char* message = "Hello, this is a message!";
sprintf(request, "POST / HTTP/1.1\r\n"
"Host: %s\r\n"
"Content-Type: text/plain\r\n"
"Content-Length: %lu\r\n"
"Connection: close\r\n\r\n"
"%s", SERVER, strlen(message), message);

// 发送请求
send(sock, request, strlen(request), 0);

// 接收响应
while ((bytes_received = recv(sock, response, sizeof(response) - 1, 0)) > 0) {
response[bytes_received] = '\0'; // 添加字符串结束符
printf("%s", response); // 打印响应
}

// 关闭套接字
closesocket(sock);
WSACleanup();
getche();
return 0;
}

  1. 运行WInServer.exe后再运行WinClient.exe
  2. 运行成功