WinPhone推送功能的C语言实现

WinPhone推送功能的C语言实现。

直接上源代码:

// wppush.c
// 在Linux下编译:gcc -o wppush  wppush.c -luuid


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <uuid/uuid.h>


int htconnect(char *host, int port)
{
	int white_sock;
	struct hostent * site;
	struct sockaddr_in me;

	site = gethostbyname(host);
	if (site==NULL) 
		return -2;

	white_sock = socket(AF_INET,SOCK_STREAM,0);
	if (white_sock <0) 
		return -1;

	memset(&me, 0, sizeof(struct sockaddr_in));
	memcpy(&me.sin_addr, site-> h_addr_list[0], site-> h_length);
	me.sin_family = AF_INET;
	me.sin_port = htons(port);

	return (connect(white_sock, (struct sockaddr *)&me,sizeof(struct sockaddr)) <0) ? -1 : white_sock;
}

int htsend(int sock, char *fmt, ...)
{
	char BUF[1024];
	va_list argptr;
	va_start(argptr,fmt);
	vsprintf(BUF,fmt,argptr);
	va_end(argptr);
	printf("\n%s\n",BUF);
	return send(sock,BUF,strlen(BUF),0);
}

void uuid2string(const uuid_t uu, char* const str)
{
	int i;
	for(i=0;i<16;i++)
		sprintf(str+i*2, "%02X",uu[i]);
	return;
}

char * mystrcat(char *dest, char *fmt, ...)
{
	va_list argptr;
	char buf[1024];

	va_start(argptr, fmt);
	vsprintf(buf, fmt, argptr);
	va_end(argptr);

	return strcat(dest, buf);
}


void wppush1(int sock, char* deviceToken, char* alert, int badge, int type, char* svrip)
{
	int   	n;
	uuid_t 	uu;
	char  	guid[200];
		char  	buf1[512];
	char  	buf2[1024];

	uuid_generate(uu);
	uuid2string(uu, guid); // 把uuid转成字符串。

	sprintf(buf1, "%s%d%s", "<?xml version=\"1.0\" encoding=\"utf-8\"?><wp:Notification xmlns:wp=\"WPNotification\"><wp:Tile><wp:BackgroundImage></wp:BackgroundImage><wp:Count>", badge, "</wp:Count><wp:Title>qq</wp:Title></wp:Tile></wp:Notification>");

	n = strlen(buf1);

	sprintf(buf2, "%s%s%s%c%c", "POST ",deviceToken," HTTP/1.1",13,10);
	mystrcat(buf2, "%s%c%c", "Content-Type: text/xml; charset=utf-8",13,10);
	mystrcat(buf2, "%s%s%c%c", "X-MessageID: ",guid,13,10);
	mystrcat(buf2, "%s%c%c", "X-NotificationClass: 1",13,10);
	mystrcat(buf2, "%s%c%c", "X-WindowsPhone-Target: token",13,10);
	mystrcat(buf2, "%s%s%c%c", "Host: ",svrip,13,10);
	mystrcat(buf2, "%s%d%c%c", "Content-Length: ",n,13,10);
	mystrcat(buf2, "%s%c%c", "Expect: 100-continue",13,10);
	mystrcat(buf2, "%s%c%c%c%c", "Connection: Keep-Alive",13,10,13,10);
	strcat(buf2, buf1);

	printf("%s\n", buf2);

	htsend(sock, buf2);

	return;
}

	
void wppush2(int sock, char* deviceToken, char* alert, int badge, int type, char* svrip, int identifier)
{
	int   	n;
	uuid_t 	uu;
	char  	guid[200];
		char  	buf1[512];
	char  	buf2[1024];

	uuid_generate(uu);
	uuid2string(uu, guid); // 把uuid转成字符串。
	
		if (0 == type)
		{
			sprintf(buf1, "%s%s%s", "<?xml version=\"1.0\" encoding=\"utf-8\"?><wp:Notification xmlns:wp=\"WPNotification\"><wp:Toast><wp:Text1>telephone</wp:Text1><wp:Text2>", alert, "</wp:Text2></wp:Toast></wp:Notification>");
		}else if (3 == type)
		{
			sprintf(buf1, "%s%s%s%d%s", "<?xml version=\"1.0\" encoding=\"utf-8\"?><wp:Notification xmlns:wp=\"WPNotification\"><wp:Toast><wp:Text1>group message</wp:Text1><wp:Text2>", alert,"</wp:Text2><wp:Param>/StartPage.xaml?groupid=", identifier, "</wp:Param></wp:Toast></wp:Notification>");
		}else
		{
			sprintf(buf1, "%s%d%s", "<?xml version=\"1.0\" encoding=\"utf-8\"?><wp:Notification xmlns:wp=\"WPNotification\"><wp:Toast><wp:Text1>message</wp:Text1><wp:Text2>Hi, 有新消息!</wp:Text2><wp:Param>/StartPage.xaml?umid=", identifier, "</wp:Param></wp:Toast></wp:Notification>");
		}

		n = strlen(buf1);

		sprintf(buf2, "%s%s%s%c%c", "POST ", deviceToken, " HTTP/1.1", 13, 10);
		mystrcat(buf2, "%s%c%c", "Content-Type: text/xml; charset=utf-8", 13, 10);
		mystrcat(buf2, "%s%s%c%c", "X-MessageID: ",guid,13,10);
		mystrcat(buf2, "%s%c%c", "X-NotificationClass: 2",13,10);
		mystrcat(buf2, "%s%c%c", "X-WindowsPhone-Target: toast",13,10);
		mystrcat(buf2, "%s%s%c%c", "Host: ",svrip,13,10);
		mystrcat(buf2, "%s%d%c%c", "Content-Length: ",n,13,10);
		mystrcat(buf2, "%s%c%c", "Expect: 100-continue",13,10);
		mystrcat(buf2, "%s%c%c%c%c", "Connection: Keep-Alive",13,10,13,10);
		strcat(buf2, buf1);

		htsend(sock, buf2);

		return;
}

void wppush4(int sock, char* deviceToken, char* alert, int badge, int type, char* svrip, int identifier)
{
	int   	n;
	uuid_t 	uu;
	time_t 	timetmp;
	char  	guid[200];
	char 	buf[100];
		char  	buf1[512];
	char  	buf2[1024];

	uuid_generate(uu);
	uuid2string(uu, guid); // 把uuid转成字符串。

	time(&timetmp); 
	ctime_r(&timetmp, buf);

	printf("%d, %s\n", timetmp, buf);
	n = strlen(buf);
	while('\n' == buf[--n]);
	buf[n+1] = '\0';

	sprintf(buf1, "%s%c%c", "<?xml version=\"1.0\" encoding=\"utf-8\"?>", 13, 10);
	mystrcat(buf1, "%s%c%c", "<Notification xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"WPNotification\">", 13, 10);
	mystrcat(buf1, "%s%s%s%c%c", "<Name xmlns=\"\">", alert, ":</Name>", 13, 10);
	mystrcat(buf1, "%s%d%s%c%c", "<Number xmlns=\"\">", identifier, "</Number>", 13, 10);
	mystrcat(buf1, "%s%d%s%c%c", "<DateTime xmlns=\"\">", buf, "</DateTime>", 13, 10);
	mystrcat(buf1, "%s%d%s%c%c", "<Count xmlns=\"\">", badge, "</Count>", 13, 10);
	mystrcat(buf1, "%s%c%c%s", "<SessionId xmlns=\"\"></SessionId>", 13, 10, "</Notification>");

	n = strlen(buf1);

	sprintf(buf2, "%s%s%s%c%c", "POST ", deviceToken, " HTTP/1.1", 13, 10);
	mystrcat(buf2, "%s%c%c", "Content-Type: text/xml; charset=utf-8", 13, 10);
	mystrcat(buf2, "%s%c%c", "X-NotificationClass: 4",13,10);
	mystrcat(buf2, "%s%c%c", "Host: db3.notify.live.net", 13, 10);
	mystrcat(buf2, "%s%d%c%c", "Content-Length: ",n,13,10);
	mystrcat(buf2, "%s%c%c", "Expect: 100-continue",13,10);
	mystrcat(buf2, "%s%c%c%c%c", "Connection: Keep-Alive",13,10,13,10);
	strcat(buf2, buf1);

	htsend(sock, buf2);

	return;
}

void wppush5(int sock, char* deviceToken, char* alert, int badge, int type, char* svrip)
{
	int   	n;
	uuid_t 	uu;
	time_t 	timetmp;
	char  	guid[200];
	char 	buf[100];
		char  	buf1[512];
	char  	buf2[1024];

	uuid_generate(uu);
	uuid2string(uu, guid); // 把uuid转成字符串。

	sprintf(buf1, "%s%d%s", "<?xml version=\"1.0\" encoding=\"utf-8\"?><wp:Notification xmlns:wp=\"WPNotification\" Version=\"2.0\"> <wp:Tile Template=\"IconicTile\"><wp:WideContent1>message</wp:WideContent1><wp:WideContent2>Hi, 有新消息!</wp:WideContent2><wp:WideContent3> </wp:WideContent3><wp:BackgroundImage></wp:BackgroundImage><wp:Count>", badge, "</wp:Count><wp:BackgroundColor></wp:BackgroundColor></wp:Tile></wp:Notification>");

	n = strlen(buf1);

	sprintf(buf2, "%s%s%s%c%c", "POST ", deviceToken, " HTTP/1.1", 13, 10);
	mystrcat(buf2, "%s%c%c", "Content-Type: text/xml; charset=utf-8", 13, 10);
	mystrcat(buf2, "%s%s%c%c", "X-MessageID: ",guid,13,10);
	mystrcat(buf2, "%s%c%c", "X-NotificationClass: 1",13,10);
	mystrcat(buf2, "%s%c%c", "X-WindowsPhone-Target: token",13,10);
	mystrcat(buf2, "%s%s%c%c", "Host: ",svrip, 13, 10);
	mystrcat(buf2, "%s%d%c%c", "Content-Length: ", n, 13, 10);
	mystrcat(buf2, "%s%c%c", "Expect: 100-continue", 13, 10);
	mystrcat(buf2, "%s%c%c%c%c", "Connection: Keep-Alive",13,10,13,10);
	strcat(buf2, buf1);

	htsend(sock, buf2);

	return;
}


void wppush6(int sock, char* deviceToken, char* alert, int badge, int type, char* svrip, int identifier)
{
	int   	n;
	uuid_t 	uu;
	time_t 	timetmp;
	char  	guid[200];
	char 	buf[100];
		char  	buf1[512];
	char  	buf2[1024];

	uuid_generate(uu);
	uuid2string(uu, guid); // 把uuid转成字符串。

	if(0 == type)
	{
		sprintf(buf1, "%s%s%s", "<?xml version=\"1.0\" encoding=\"utf-8\"?><wp:Notification xmlns:wp=\"WPNotification\"><wp:Toast><wp:Text1>telephone</wp:Text1><wp:Text2>", alert, "</wp:Text2></wp:Toast></wp:Notification>");

	}else if(1 == type)
	{
		sprintf(buf1, "%s%d%s", "<?xml version=\"1.0\" encoding=\"utf-8\"?><wp:Notification xmlns:wp=\"WPNotification\"><wp:Toast><wp:Text1>message</wp:Text1><wp:Text2>Hi, 有新消息!</wp:Text2><wp:Param>/View/ChatView.xaml?type=1&index=0&id=", identifier, "</wp:Param></wp:Toast></wp:Notification>");
	}else if(3 == type)
	{
		sprintf(buf1, "%s%d%s%d%s", "<?xml version=\"1.0\" encoding=\"utf-8\"?><wp:Notification xmlns:wp=\"WPNotification\"><wp:Toast><wp:Text1>group message</wp:Text1><wp:Text2>", alert, "</wp:Text2><wp:Param>/StartPage.xaml?groupid=", identifier, "</wp:Param></wp:Toast></wp:Notification>");
	}else
	{
		return;
	}

	n=strlen(buf1);

	sprintf(buf2, "%s%s%s%c%c", "POST ", deviceToken, " HTTP/1.1", 13, 10);
	mystrcat(buf2, "%s%c%c", "Content-Type: text/xml; charset=utf-8", 13, 10);
	mystrcat(buf2, "%s%s%c%c", "X-MessageID: ",guid,13,10);
	mystrcat(buf2, "%s%c%c", "X-NotificationClass: 2",13,10);
	mystrcat(buf2, "%s%c%c", "X-WindowsPhone-Target: toast",13,10);
	mystrcat(buf2, "%s%s%c%c", "Host: ",svrip, 13, 10);
	mystrcat(buf2, "%s%d%c%c", "Content-Length: ", n, 13, 10);
	mystrcat(buf2, "%s%c%c", "Expect: 100-continue", 13, 10);
	mystrcat(buf2, "%s%c%c%c%c", "Connection: Keep-Alive",13,10,13,10);
	strcat(buf2, buf1);

	htsend(sock, buf2);

	return;
}


void wppush7(int sock, char* deviceToken, char* alert, int badge, int type, char* svrip, int identifier)
{
	int   	n;
	uuid_t 	uu;
	time_t 	timetmp;
	char  	guid[200];
	char 	buf[100];
		char  	buf1[512];
	char  	buf2[1024];

	uuid_generate(uu);
	uuid2string(uu, guid); // 把uuid转成字符串。

	time(&timetmp); 
	ctime_r(&timetmp, buf);

	printf("%d, %s\n", timetmp, buf);
	n = strlen(buf);
	while('\n' == buf[--n]);
	buf[n+1] = '\0';

	sprintf(buf1, "%s%c%c", "<?xml version=\"1.0\" encoding=\"utf-8\"?>", 13, 10);
	mystrcat(buf1, "%s%c%c", "<Notification xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"WPNotification\">", 13, 10);
	mystrcat(buf1, "%s%s%s%c%c", "<Name xmlns=\"\">", alert, ":</Name>", 13, 10);
	mystrcat(buf1, "%s%d%s%c%c", "<Number xmlns=\"\">", identifier, "</Number>", 13, 10);
	mystrcat(buf1, "%s%s%s%c%c", "<DateTime xmlns=\"\">", buf, "</DateTime>", 13, 10);
	mystrcat(buf1, "%s%d%s%c%c", "<Count xmlns=\"\">", badge, "</Count>", 13, 10);
	mystrcat(buf1, "%s%s%s%c%c", "<SessionId xmlns=\"\">", alert, "</SessionId>", 13, 10);
	mystrcat(buf1, "%s%c%c%s", "<Type xmlns=\"\">0</Type>", 13, 10, "</Notification>");

	n = strlen(buf1);

	sprintf(buf2, "%s%s%s%c%c", "POST ", deviceToken, " HTTP/1.1", 13, 10);
	mystrcat(buf2, "%s%c%c", "Content-Type: text/xml; charset=utf-8", 13, 10);
	mystrcat(buf2, "%s%c%c", "X-NotificationClass: 4",13,10);
	mystrcat(buf2, "%s%c%c", "Host: db3.notify.live.net", 13, 10);
	mystrcat(buf2, "%s%d%c%c", "Content-Length: ", n, 13, 10);
	mystrcat(buf2, "%s%c%c", "Expect: 100-continue", 13, 10);
	mystrcat(buf2, "%s%c%c%c%c", "Connection: Keep-Alive",13,10,13,10);
	strcat(buf2, buf1);

	htsend(sock, buf2);

	return;
}


int main(int argc,char **argv)
{
	int  n, socket;
	char buf[2048];

	if (argc<2)
	{
		printf( "Please input the hostName. Example:\n %s www.sohu.com\n ",argv[0]);
		return;
	}
	socket = htconnect(argv[1],80);
	if (socket <1) 
	{
		printf( "create connecct failed. socket: %d\n", socket);
		return;
	}

	printf("发送推送请求:\n");

	wppush6(socket, "http://hk1.notify.live.net/throttledthirdparty/01.00/AQEtF6fm0DuxQLG2iJZViohVAgAAAAADehADAAQUZm52OjJCNUZFOUUyQTMzOUI0RjQFBkxFR0FDWQ","This is message test.", 3, 1, "hk1.notify.live.net", 20056);

	printf("\n接收推送服务器返回的信息:\n\n");

	n = read(socket, buf, sizeof(buf));
	buf[n] = '\0';
	printf("%s",buf);

	close(socket);
}


执行结果(举例):

# ./wppush hk1.notify.live.net
发送请求开始
... ...

接收推送服务器返回的信息:

HTTP/1.1 200 OK
Cache-Control: private
Server: Microsoft-IIS/7.5
X-DeviceConnectionStatus: Connected
X-NotificationStatus: Received
X-SubscriptionStatus: Active
X-MessageID: b3bc6d8c-179d-4b4c-9642-c1674a86820b
ActivityId: 18bb002b-d2bc-4254-9acf-c4c596dbd14c
X-Server: HK1MPNSM016
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 10 Jan 2012 09:32:39 GMT
Content-Length: 0



你可能感兴趣的:(WinPhone推送功能的C语言实现)