70,040
社区成员
发帖
与我相关
我的任务
分享#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<winsock2.h>
#include<windows.h>
#include<string.h>
#pragma comment(lib, "ws2_32.lib")
typedef struct{
char line[256];
char head[256];
char body[256];
}message;
void main(){
int num;
SOCKET sfd;
WSADATA wsa;
struct sockaddr_in serv;
message req;
char sndBuf[1024], rcvBuf[1024];
WSAStartup(MAKEWORD(2, 1), &wsa);
if ((sfd = socket(AF_INET, SOCK_STREAM, 0))<0){
perror("socket error!");
exit(1);
}
memset(&serv, 0, sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_port = htons(80);
//BING 70.37.92.127
//BAIDU 115.239.210.26
//baidu api 180.149.132.118
//google 74.125.31.99
serv.sin_addr.S_un.S_addr = inet_addr("74.125.31.99");
if ((connect(sfd, (struct sockaddr *)&serv, sizeof(serv)))<0){
perror("connet error!");
exit(1);
}
memset(sndBuf, 0, 1024);
memset(rcvBuf, 0, 1024);
char u_name[50] = "我是中国人ABC";
char header_name[100] = "0";
char header_end[100] = "0";
sprintf(header_name,"User-name:%s\r\n", u_name);
strcpy(header_end, "X-Power:XXX\r\n\r\n");
strcpy(req.line, "GET /video/?act=api&op=test HTTP/1.0\r\n"
"Host:v.xxx.com\r\n"
"User-Agent:whatever\r\n"
"Accept-Type:*/*\r\n"
"Connection:close\r\n"
"User-Token:6666\r\n");
strcat(req.line, header_name);
strcat(req.line, header_end);
strcat(sndBuf, req.line);
strcpy(req.head, "\r\n");
strcat(sndBuf, req.head);
puts(sndBuf);
if ((num = send(sfd, sndBuf, 1024, 0))<0){
perror("send error!");
exit(1);
}
puts("send success!\n");
do{
if ((num = recv(sfd, rcvBuf, 2048, 0))<0){
perror("recv error!");
exit(1);
}
else if (num>0){
printf("%s", rcvBuf);
memset(rcvBuf, 0, 1024);
}
} while (num>0);
puts("\nread success!\n");
closesocket(sfd);
WSACleanup();
system("pause");
}
char u_name[50] = "我是中国人ABC";
char header_name[100] = "0";
char header_end[100] = "0";
int len_l = (int)strlen(u_name);
WCHAR *ucp;
ucp = (WCHAR *)calloc((len_l + 1), sizeof(WCHAR));
int r = MultiByteToWideChar(CP_OEMCP, 0, u_name, -1, ucp, len_l + 1);
知识扩充
------------------------CP_ACP和CP_OEMCP start----------------------------
Windows API函数MultiByteToWideChar用于多字节编码字符串向宽字符串(即UTF-16 LE)的转码。它的第一个参数的常用值是CP_ACP和CP_OEMCP。这到底指的是什么代码页呢? 我编了小程序做了实验。
CP_ACP和CP_OEMCP,分别是指当前计算机上的Windows操作系统的Windows代码页与OEM代码页。对于东亚的简体中文、繁体中文、日文、韩文等Win操作系统语言环境,这两种代码页是同一个,如简体中文是代码页936即GB2312字符集,繁体中文是950即大五码字符集,韩文是949、日文是932。对于西方国家的拼音文字语言设置,两个代码页不同。典型的如English_US,其Windows代码页是1252、OEM代码页是437,还有第三个代码页ISO-8859-1又称Latin-1或“西欧语言”,是针对英语法语西语德语等西欧语言的扩展ASCII字符集。这三者(1252、437、8859-1)都是针对英语但并不相同。
为什么会有Windows代码页与OEM代码页的区别呢?因为在八十年代DOS系统时期,还是“字符终端”的屏幕只能够显示的256个字符,这些字符的字形的点阵信息存储在硬件的ROM中。DOS操作系统通过系统中断调用驱动程序把这些字形读出来写入显存。这是由OEM负责字符集中有哪些字符,显示时为什么字形的时代,而且一台PC上只有这么一套字符集/字形,没得选,除非你再差一个带字库的“汉卡”。进入了微软的Windows操作系统时代之后,由于硬件的发展,操作系统有了自己的字形文件,绘制字符时不再真地去读ROM,而是用字形文件(就是字体fonts文件)来把字符的形状写入显存。可以选择用哪种字形:如有衬线的Times NewRome,还是无衬线的Sans Serif。操作系统默认使用的字符集,就由微软来定义了,如English_US使用Codepage1252;简体中文使用Codepage936(即国标2312). 至于那个OEM436,就是legacy,用于向后兼容。
综上,就这么点事。CP_ACP和CP_OEMCP,分别是UINT的0和1。在WinNls.h中的注释说明分别是“default to ANSI code page”,“default to OEM code page”。所以,在简体中文Windows,这两个宏表示的都是代码页936.
下述程序代码片段用于测试
UINT codepage=936;
char str[]="我们中国"; //这个char[]必然是多字节编码字符串
DWORD len;
// 得到我们要转换的MyString为UNICODE所需要的UNICODE缓冲区的长度
len = MultiByteToWideChar(codepage, 0, str, -1, 0, 0);
wchar_t *buf=new wchar_t[len+10];
MultiByteToWideChar(codepage, 0, str, -1, buf, len);
setlocale(LC_CTYPE,"");//把当前locale字符环境从C/C++缺省的"C"设置,改为操作系统的设置(即代码页936)
wprintf(L"%s",buf); //因为这个C标准库函数的实现,是把宽字符输入又转化为多字节字符去显示,所以必须正确设置当前操作系统的多字节编码的代码页
结果:
1. 输入是char str[]="我们中国"; UINT codepage=936或者54936(这是GB18030代码页)或者CP_ACP或者CP_OEMCP,都能正确打印出结果“我们中国”。
2. 输入是char str[]="иい瓣"; UINT codepage=950; 也能正确把上述大五码字符串打印出宽字符串输出结果“我们中国”。
3. 输入是char str[]="鎴戜滑涓浗 "; UINT codepage=65001; 也能正确把上述UTF-8字符串打印出宽字符串输出结果“我们中国”。
附录:
一个在线GB/BIG5/UTF-8/UNICODE转码的网站http://www.dheart.net/bmzh/index.php
ps. 实际上,简体中文Windows系统的默认代码页936,不是只有6763个汉字的GB2316,正确说法是自1995年Windows95起,代码页936是GBK字符集,包含了20902个汉字。此前,代码页936与GB2316是一样的。GB2316 >> GBK >> GB18030 是向后兼容的。所以编程角度把这三者视作等同,也凑合啦。
------------------------CP_ACP和CP_OEMCP end----------------------------
MultiByteToWideChar
函数功能:该函数映射一个字符串到一个宽字符(unicode)的字符串。由该函数映射的字符串没必要是多字节字符组。(此函数把多字节字符串转换成宽字符串(Unicode),待转换的字符串并不一定是多字节的。)
函数原型:
int MultiByteToWideChar(
UINT CodePage,
DWORD dwFlags, //一组位标记用以指出是否未转换成预作或宽字符(若组合形式存在),是否使用象形文字替代控制字符,以及如何处理无效字符。你可以指定下面是标记常量的组合
LPCSTR lpMultiByteStr, //指向将被转换字符串的字符
int cchMultiByte, //指定由参数lpMultiByteStr指向的字符串中字节的个数。如果lpMultiByteStr指定的字符串以空字符终止,可以设置为-1(如果字符串不是以空字符中止,设置为-1可能失败,可能成功),此参数设置为0函数将失败。
LPWSTR lpWideCharStr, //指向接收被转换字符串的缓冲区
int cchWideChar //指定由参数lpWideCharStr指向的缓冲区的宽字符个数
);