Chinaunix首页 | 论坛 | 博客
  • 博客访问: 237987
  • 博文数量: 68
  • 博客积分: 884
  • 博客等级: 准尉
  • 技术积分: 700
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-25 14:34
文章分类

全部博文(68)

文章存档

2016年(3)

2015年(4)

2014年(9)

2013年(8)

2012年(6)

2011年(19)

2010年(19)

我的朋友

分类:

2010-07-05 00:18:12

#if defined(__MINGW32__)
    #include
#else
    #include
    #include socket.h>

    #define closesocket close

#endif
#include

#define D_PORT      4344
#define D_HOST      "localhost"
#define D_QUEUE     32
#define D_SOCKETS   16
#define D_INFO      256


#if defined(__MINGW32__)

#define bzero(x,y)      memset((x), 0x00, (y))

#define sleep(t) _sleep((t) * 1000)

#endif


int main(int argc, char **argv) {
    struct timeval tv;
    struct sockaddr_in addr;
    struct hostent *host;
    unsigned int descriptor;
    int result;
    int index;
    int cycle = 0;
    int delay = 0;
    unsigned int sockets[D_SOCKETS];
    int sockets_index = 0;
    unsigned int maximun;
    char buffer[D_INFO];
    fd_set input;

    /*  read the delay if any  */
    if (argc > 1)
        delay = atol(argv[1]);
    else
        delay = 0;

#if defined(__MINGW32__)
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif  /*  WIN32  */

    /*  create a socket  */
    descriptor = socket(PF_INET, SOCK_STREAM, 0);
    if (descriptor == -1) {
        perror("socket");
        return (1);
    }

    /*  get information about the host  */
    memset(&addr, 0, sizeof(addr));
    host = gethostbyname(D_HOST);
    if (host == NULL) {
        perror("gethostbyname");
        closesocket(descriptor);
#if defined(__MINGW32__)
        WSACleanup();
#endif
        return (1);
    }

    /*  bind the socket to an address and port  */
    memcpy(&addr.sin_addr, host->h_addr_list[0], sizeof(host->h_addr_list[0]));
    addr.sin_family = AF_INET;
    addr.sin_port   = htons(D_PORT);
    result = bind(descriptor, (struct sockaddr *)&addr, sizeof(addr));
    if (result == -1) {
        perror("bind");
        closesocket(descriptor);
#if defined(__MINGW32__)
        WSACleanup();
#endif
        return (1);
    }

    /*  listen for connections  */
    result = listen(descriptor, D_QUEUE);
    if (result == -1) {
        perror("listen");
        closesocket(descriptor);
#ifdef WIN32
        WSACleanup();
#endif
        return (1);
    }

    memset(sockets, 0, sizeof(sockets));
    maximun = descriptor;

    result = 0;
    while (result != -1) {
        FD_ZERO(&input);
        FD_SET(descriptor, &input);
        for (result = 0; result < sockets_index; result++)
            FD_SET(sockets[result], &input);

        tv.tv_sec  = delay;
        tv.tv_usec = 0;
        if (delay == -1)
            result = select(maximun + 1, &input, NULL, NULL, NULL);
        else
            result = select(maximun + 1, &input, NULL, NULL, &tv);
        switch (result) {
            /*  error in select  */
            case -1:
                perror("select");
                break;

            /*  nothing to process  */
            case 0:
                break;

            /*  a number of sockets are ready for reading  */
            default:
                /*  check if the descriptor set is our listening one  */
                if (FD_ISSET(descriptor , &input)) {
                    sockets[sockets_index] = accept(descriptor, NULL, NULL);
                    if (sockets[sockets_index] == -1) {
                        perror("accept");
                    }
                    else {
                        if (sockets[sockets_index] > maximun)
                            maximun = sockets[sockets_index];

                        sockets_index++;
                    }
                }
                /*  one of the sockets is sending data. Find it  */
                else {
                    for (index = 0; index < sockets_index; index++) {
                        if (FD_ISSET(sockets[index], &input)) {
                            memset(buffer, 0, sizeof(buffer));

                            /*  read information from socket  */
                            result = recv(sockets[index], buffer, sizeof(buffer), 0);
                            if (result == -1)
                                perror("recv");
                            else
                                printf("Received %d bytes from descriptor %d: %s\n", result, sockets[index], buffer);
                        }
                    }
                }
        }

        printf("%d\r", cycle++);
    }

    for (result = 0; result < sockets_index; result++) {
        closesocket(sockets[sockets_index]);
    }

    closesocket(descriptor);
#if defined(__MINGW32__)
    WSACleanup();
#endif

    return (0);
}


Ok, here is a very small program. Put this into a file and add it to a VC project, add Ws2_32.lib library for linking, and compile it. Under MinGW, use g++ main.cpp -o main.exe -lwsock32. Execute it. By default, it is a non blocking program. There is a number counting advancing to show you it is not blocking the execution.

Now, run a telnet (telnet localhost 4344). Telnet will connect, and everytime you type something, it will send the letter to the server. You can connect up to 32 telnets. Every time you type a letter, the server prints the socket and the letter. If you see the Task Manager, the program would be taking like 99% of CPU.

If you want your server to wait for 1 second before continuing processing, pass 1 as argument. You will notice I set the new delay. This time, the server will wait for 1 second before continuing with the program. Finally, if you want to make the program blocking, pass -1 as argument. If you check the code, I call select with NULL as last parameter to block it.

Be careful! I am not doing error handling when a telnet shuts down, so if you do it will get mad  I hope the example is good enough.

(Edited: Non-Windows support is not tested, too sleepy to turn my other computer on, but should work with one or two hacks).

original url : 


Compile command :

i586-mingw32msvc-gcc -g -Wall -o snmp_cm_get_mac.exe test_snmp.c -lwsock32

阅读(1398) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~