用一个控制台程序一直做一件事情 就是在main里面放了个死循环 程序一般开启后就不结束,唯一结束方式是强制结束,怎么才能保证退出时的安全性。

解决方案 »

  1.   

    控制台使用mfc库吗??
    可以在控制台与一个控制程序中共享一个信号量的方式,实现获取程序是否结束的消息
      

  2.   

    不使用mfc 非windows平台 很纯粹的控制台程序 只有一个main
      

  3.   

    #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里查看。
      

  4.   

    那应该是用winapi截获了close消息
    可惜我不在windows上作(对其消息很不熟) msdn好像查不到:-(
    有没有比较好的解决思路?不一定是要代码
      

  5.   

    在"Win32多线程程序设计"中有详细的描述,方法无外乎两种:
    1 程序中没有等等信号量的地方,你可以在死循环的开头做一个判断,
     while(1)
    {
      if (bExit) then break;
      ...
    }2 程序中有等待信号量的地方,你可以使用WaitForMultiObject来判断,当然其中一个信号量是其他线程控制的一个退出标志.
      while(1)
     {
     ...
      if WaitForSingleObject(h, ...) = ...  
     ...
     }
      

  6.   

    楼上的:不是win32 也不是多线程
      

  7.   

    POSIX下用信号,Win32用SetConsoleCtrlHandler。
    另外,非win32开发来这里问?