MinGW Socket

#ifdef WIN32
    #include <Winsock2.h>
#else
    #include <sys/types.h>
    #include <sys/socket.h>

    #define closesocket close
#endif
#include <stdio.h>

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

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;

#ifdef WIN32
    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);
#ifdef WIN32
        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);
#ifdef WIN32
        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);
#ifdef WIN32
    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 : http://www.allegro.cc/forums/thread/370013/370226#target

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值