怎样安全退出? 用一个控制台程序一直做一件事情 就是在main里面放了个死循环 程序一般开启后就不结束,唯一结束方式是强制结束,怎么才能保证退出时的安全性。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 控制台使用mfc库吗??可以在控制台与一个控制程序中共享一个信号量的方式,实现获取程序是否结束的消息 不使用mfc 非windows平台 很纯粹的控制台程序 只有一个main #pragma comment(lib,"ws2_32.lib")#include <stdio.h>#include <winsock2.h>#include <mstcpip.h>//IP数据报首部(固定的20字节)typedef struct _iphdr{ unsigned char ver_len; //8 bites, version(4 bites) and length of the header(4 bites) unsigned char tos; //8 bites,type of service unsigned short total_len; //16 bites,total length of the packet unsigned short identity; //16 bites,identity unsigned short frag_flags; //16 bites,frag(3 bites) and flags(13 bites)--offset in the group unsigned char ttl; //8 bites,time of live unsigned char protocal; //8 bites,the protocal the ip server for unsigned short checksum; //16 bites,check sum for the header of the ip unsigned int sourceIP; //32 bites,source ip unsigned int destIP; //32 bites,dest ip}IpHeader;#define PACKET_SIZE sizeof(IpHeader)#define xmalloc(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s))#define xfree(p) HeapFree(GetProcessHeap(),0,(p))BOOL g_bExit = FALSE;BOOL WINAPI CtrlHandler(DWORD dwEvent);void HandleErr(char * funcname);int main(int argc,char * argv[]){ if(!SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler,TRUE)) { HandleErr("SetConsoleCtrlHandle"); return -1; } WSADATA wsaData; if(WSAStartup(MAKEWORD(2,2),&wsaData) != 0) { HandleErr("WSAStartup"); return -1; } SOCKET sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP); if(sock == SOCKET_ERROR) { HandleErr("socket"); WSACleanup(); return -1; } //获取本机IP char szLocal[80]; if(gethostname(szLocal,80)== SOCKET_ERROR) { HandleErr("gethostname"); return -1; } struct hostent * local; memset(&local,0,sizeof(local)); if((local = gethostbyname(szLocal)) == NULL) { HandleErr("gethostbyname"); return -1; } struct sockaddr_in addr; memset(&addr,0,sizeof(addr)); //addr.sin_addr.S_un.S_addr = inet_addr("192.168.102.1"); memcpy(&(addr.sin_addr),local->h_addr_list[0]/*local->h_addr*/,local->h_length); addr.sin_family = AF_INET; printf("Local IP is %s \n",inet_ntoa(addr.sin_addr)); if(bind(sock,(const struct sockaddr *)&addr,sizeof(addr)) == -1) { HandleErr("bind"); closesocket(sock); WSACleanup(); return -1; } int on = RCVALL_ON; DWORD num; if(WSAIoctl(sock,SIO_RCVALL,(LPVOID)&on,sizeof(on),NULL,0,&num,NULL,NULL) == -1) { HandleErr("WSAIoctl"); return -1; } char * buff = (char *)xmalloc(PACKET_SIZE); if(buff == NULL) { HandleErr("xmalloc"); return -1; } struct sockaddr_in from; int fromlen = sizeof(from); while(!g_bExit) { static int nCount = 0; memset(buff,0,PACKET_SIZE); memset(&from,0,fromlen); if(recvfrom(sock,buff,PACKET_SIZE,0,(struct sockaddr *)&from,&fromlen) == SOCKET_ERROR) { if(WSAGetLastError() != WSAEMSGSIZE) { HandleErr("recvfrom"); return -1; } } printf("%d -- ",nCount ++); switch(((IpHeader *)buff )->protocal) { case IPPROTO_ICMP: printf("ICMP from %s \n",inet_ntoa(from.sin_addr)); break; case IPPROTO_IGMP: printf("IGMP from %s \n",inet_ntoa(from.sin_addr)); break; case IPPROTO_UDP: printf("UDP from %s \n",inet_ntoa(from.sin_addr)); break; case IPPROTO_TCP: printf("TCP from %s \n",inet_ntoa(from.sin_addr)); break; default: printf("Unknown datagram from %s =n",inet_ntoa(from.sin_addr)); } } xfree(buff); closesocket(sock); WSACleanup(); printf("stopped \n"); return 0;}BOOL WINAPI CtrlHandler(DWORD dwEvent){ switch(dwEvent) { case CTRL_C_EVENT: case CTRL_LOGOFF_EVENT: case CTRL_SHUTDOWN_EVENT: case CTRL_CLOSE_EVENT: printf("Stopping....\n"); g_bExit = TRUE; break; default: return FALSE; } return TRUE;}void HandleErr(char * funcname){ printf("%s function called fail. \n",funcname); return ;}这也是一个一开启就死循环的程序,安全退出可以在CtrlHandler里实现,或者在main函数中while控制块后面。SetConsoleCtrlHandler可以在msdn里查看。 那应该是用winapi截获了close消息可惜我不在windows上作(对其消息很不熟) msdn好像查不到:-(有没有比较好的解决思路?不一定是要代码 在"Win32多线程程序设计"中有详细的描述,方法无外乎两种:1 程序中没有等等信号量的地方,你可以在死循环的开头做一个判断, while(1){ if (bExit) then break; ...}2 程序中有等待信号量的地方,你可以使用WaitForMultiObject来判断,当然其中一个信号量是其他线程控制的一个退出标志. while(1) { ... if WaitForSingleObject(h, ...) = ... ... } 楼上的:不是win32 也不是多线程 POSIX下用信号,Win32用SetConsoleCtrlHandler。另外,非win32开发来这里问? Microsoft Visual C++ 2012 RC 编译后的程序不能在windows 2003下运行 怎么获得文件的路径? 请教在vs2005建立项目,使用DLL建类并使用不了? CFile::mode Create|CFile::ReadWrite的含义! 关于 Windows NT Terminal Server的API函数 ado异常解释?? 关于调用ActiveX控件的简单问题? 怎么由显示的图像,获取图像数据 关于comboBox的问题 如何让访问数据库失败快速返回? 如何改变系统的API 如何判断客护端已断线?
可以在控制台与一个控制程序中共享一个信号量的方式,实现获取程序是否结束的消息
#include <winsock2.h>
#include <mstcpip.h>//IP数据报首部(固定的20字节)
typedef struct _iphdr
{
unsigned char ver_len; //8 bites, version(4 bites) and length of the header(4 bites)
unsigned char tos; //8 bites,type of service
unsigned short total_len; //16 bites,total length of the packet
unsigned short identity; //16 bites,identity
unsigned short frag_flags; //16 bites,frag(3 bites) and flags(13 bites)--offset in the group
unsigned char ttl; //8 bites,time of live
unsigned char protocal; //8 bites,the protocal the ip server for
unsigned short checksum; //16 bites,check sum for the header of the ip
unsigned int sourceIP; //32 bites,source ip
unsigned int destIP; //32 bites,dest ip
}IpHeader;#define PACKET_SIZE sizeof(IpHeader)
#define xmalloc(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s))
#define xfree(p) HeapFree(GetProcessHeap(),0,(p))BOOL g_bExit = FALSE;BOOL WINAPI CtrlHandler(DWORD dwEvent);
void HandleErr(char * funcname);int main(int argc,char * argv[])
{
if(!SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler,TRUE))
{
HandleErr("SetConsoleCtrlHandle");
return -1;
} WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
{
HandleErr("WSAStartup");
return -1;
} SOCKET sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP);
if(sock == SOCKET_ERROR)
{
HandleErr("socket");
WSACleanup(); return -1;
} //获取本机IP
char szLocal[80];
if(gethostname(szLocal,80)== SOCKET_ERROR)
{
HandleErr("gethostname");
return -1;
} struct hostent * local;
memset(&local,0,sizeof(local));
if((local = gethostbyname(szLocal)) == NULL)
{
HandleErr("gethostbyname");
return -1;
}
struct sockaddr_in addr;
memset(&addr,0,sizeof(addr));
//addr.sin_addr.S_un.S_addr = inet_addr("192.168.102.1");
memcpy(&(addr.sin_addr),local->h_addr_list[0]/*local->h_addr*/,local->h_length);
addr.sin_family = AF_INET;
printf("Local IP is %s \n",inet_ntoa(addr.sin_addr));
if(bind(sock,(const struct sockaddr *)&addr,sizeof(addr)) == -1)
{
HandleErr("bind");
closesocket(sock);
WSACleanup(); return -1;
} int on = RCVALL_ON;
DWORD num;
if(WSAIoctl(sock,SIO_RCVALL,(LPVOID)&on,sizeof(on),NULL,0,&num,NULL,NULL) == -1)
{
HandleErr("WSAIoctl"); return -1;
} char * buff = (char *)xmalloc(PACKET_SIZE);
if(buff == NULL)
{
HandleErr("xmalloc");
return -1;
}
struct sockaddr_in from;
int fromlen = sizeof(from); while(!g_bExit)
{
static int nCount = 0;
memset(buff,0,PACKET_SIZE);
memset(&from,0,fromlen); if(recvfrom(sock,buff,PACKET_SIZE,0,(struct sockaddr *)&from,&fromlen) == SOCKET_ERROR)
{
if(WSAGetLastError() != WSAEMSGSIZE)
{
HandleErr("recvfrom");
return -1;
}
} printf("%d -- ",nCount ++);
switch(((IpHeader *)buff )->protocal)
{
case IPPROTO_ICMP:
printf("ICMP from %s \n",inet_ntoa(from.sin_addr));
break;
case IPPROTO_IGMP:
printf("IGMP from %s \n",inet_ntoa(from.sin_addr));
break;
case IPPROTO_UDP:
printf("UDP from %s \n",inet_ntoa(from.sin_addr));
break;
case IPPROTO_TCP:
printf("TCP from %s \n",inet_ntoa(from.sin_addr));
break;
default:
printf("Unknown datagram from %s =n",inet_ntoa(from.sin_addr));
}
} xfree(buff); closesocket(sock);
WSACleanup();
printf("stopped \n"); return 0;
}BOOL WINAPI CtrlHandler(DWORD dwEvent)
{
switch(dwEvent)
{
case CTRL_C_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
case CTRL_CLOSE_EVENT:
printf("Stopping....\n");
g_bExit = TRUE;
break; default:
return FALSE;
}
return TRUE;
}void HandleErr(char * funcname)
{
printf("%s function called fail. \n",funcname);
return ;
}这也是一个一开启就死循环的程序,安全退出可以在CtrlHandler里实现,或者在main函数中while控制块后面。SetConsoleCtrlHandler可以在msdn里查看。
可惜我不在windows上作(对其消息很不熟) msdn好像查不到:-(
有没有比较好的解决思路?不一定是要代码
1 程序中没有等等信号量的地方,你可以在死循环的开头做一个判断,
while(1)
{
if (bExit) then break;
...
}2 程序中有等待信号量的地方,你可以使用WaitForMultiObject来判断,当然其中一个信号量是其他线程控制的一个退出标志.
while(1)
{
...
if WaitForSingleObject(h, ...) = ...
...
}
另外,非win32开发来这里问?