这里还是吐槽一下,时代的发展出乎了意料,互联网emoji让UTF-8成了必需品,而兼容性的要求让Windows上的C语言难以高效支持UTF-8。记得前几年个人还比较喜欢编写基于GBK的程序,现在却发现使用GBK已经很难让自己满意了。如果没有互联网和Windows的分道扬镳,C语言编程的前景会不会更美好呢?
也许互联网就不该支持emoji,可是谁能挡得住?也许Windows就应该增加广泛的UTF-8支持,谁来买单?互联网从来都没有做错什么,Windows也没有做错什么,错的是人,人总是带有文化背景的偏见的,总是怀念美好的过去的,总是不愿意接受新事物比老事物更复杂,这一令人无奈的现实的。说到底,编程爱好者还是最大输家。
也许吧,错不在时代,错在没有人编写一本经典的基于宽字符的C语言入门书。。。
经典的Windows字节版本:
// winsockhttpansi1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#include <winsock.h>
#pragma comment(lib, "ws2_32.lib")
int _tmain(int argc, _TCHAR* argv[])
{
// 初始化环境
WSADATA wsadata;
WSAStartup(MAKEWORD(2, 2), &wsadata);
// 创建本地
SOCKET sock;
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
{
printf(">> socket error\n");
return 0;
}
printf(">> socket\n");
// 绑定本地
SOCKADDR_IN addr;
addr.sin_addr.S_un.S_addr = inet_addr("0.0.0.0");
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
int retval = bind(sock, (SOCKADDR*)&addr, sizeof addr);
if (retval == SOCKET_ERROR)
{
printf(">> bind error\n");
closesocket(sock);
return 0;
}
printf(">> bind %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
// 监听
retval = listen(sock, 5);
if (retval == SOCKET_ERROR)
{
printf(">> listen error\n");
closesocket(sock);
return 0;
}
printf(">> listen\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
while (1)
{
// 接受连接
SOCKADDR_IN client_addr;
int client_addr_len = sizeof client_addr;
SOCKET client = accept(sock, (SOCKADDR*)&client_addr, &client_addr_len);
if (client == INVALID_SOCKET)
{
printf(">> accept error\n");
continue;
}
printf(">> accept %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
// 接收请求内容
char request[65536] = "";
retval = recv(client, request, 65535, 0);
if (retval == SOCKET_ERROR)
{
printf(">> recv request error\n");
closesocket(client);
continue;
}
printf(">> recv request %d\n", retval);
//printf(">> request string:\n%s\n", request);
// 生成响应内容
char content_fmt[] =
"<html>"
"<head>"
"<title>测试页面</title>"
"</head>"
"<body>"
"<form action="\"\"" method="\"post\"">"
"<input type="\"text\"" name="\"name\"">"
"<textarea name="\"text\""></textarea>"
"<input type="\"submit\"">"
"</form>"
"服务器工作正常"
"您的IP地址:%s"
"您的本地端口号:%d"
"请求头部:"
"%s"
"</body>"
"</html>";
char content[65536] = "";
_snprintf(content, 65535, content_fmt,
inet_ntoa(client_addr.sin_addr),
ntohs(client_addr.sin_port),
request);
// 生成响应头部
char header[] = "HTTP/1.1 200 OK\r\n"
"Content-Type: text/html; charset=gbk\r\n"
"\r\n";
// 发送响应头部
retval = send(client, header, strlen(header), 0);
if (retval == SOCKET_ERROR)
{
printf(">> send header error\n");
closesocket(client);
continue;
}
printf(">> send header %d\n", retval);
// 发送响应内容
retval = send(client, content, strlen(content), 0);
if (retval == SOCKET_ERROR)
{
printf(">> send content error\n");
closesocket(client);
continue;
}
printf(">> send content %d\n", retval);
// 关闭连接
closesocket(client);
printf(">> closesocket\n");
}
// 关闭本地
closesocket(sock);
printf(">> closesocket\n");
// 清理环境
WSACleanup();
return 0;
}
</winsock.h></windows.h>