zoukankan      html  css  js  c++  java
  • socket select用法:100行代码实现网络数据转发程序

    socket select用法:100行代码实现网络数据转发程序 « Xiaoxia[PG]

    socket select用法:100行代码实现网络数据转发程序

    无聊学习一下select+blocking socket的用法。不使用多线程+blocking socket的方法。

    程序从本地1998端口转发到221.130.162.247的80端口:

     

    #include <stdio.h>
    #include <winsock.h>
    #include <wininet.h>
    
    WSADATA wsaData;
    #define client_count 100
    int clients[client_count] = {0};
    int remotes[client_count] = {0};
    static void remove_client(int i)
    {
        shutdown(clients[i], SD_RECEIVE);
        closesocket(clients[i]);
        shutdown(remotes[i], SD_RECEIVE);
        closesocket(remotes[i]);
        clients[i] =
        remotes[i] = 0;
    }
    static int get_client()
    {
        int i;
        for( i = 0; i<client_count; i++)
            if(!clients[i])
                return i;
        return 0;
    }
    int main(int argc, char **argv)
    {
        fd_set fdreads, fdwrites;
        const int buf_size = 1024*32;
        char buf[buf_size];
        int ret = WSAStartup(MAKEWORD(2,1), (WSADATA*)&wsaData );
        if(ret!=0)
            perror( "failed to initialize win32 WSA" );
        int sock = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
        struct sockaddr_in addr = {0};
        struct sockaddr_in remote_addr = {0};
        addr.sin_family = remote_addr.sin_family = PF_INET;
        addr.sin_addr.s_addr = INADDR_ANY;
        addr.sin_port = htons( 1998 );
        remote_addr.sin_addr.s_addr = inet_addr("221.130.162.247");
        remote_addr.sin_port = htons( 80 );
        if( bind( sock, (struct sockaddr*)&addr, sizeof(struct sockaddr_in) ) < 0 )
            perror("failed to bind socket");
        listen( sock , 5);
        printf("listen\n");
        for(;;){
            int i, j, k;
            FD_ZERO(&fdreads);
            FD_SET( sock, &fdreads);
            for( i=0; i<client_count; i++)
                if(clients[i]){
                    FD_SET( clients[i], &fdreads );
                    FD_SET( remotes[i], &fdreads );
                }
            ret = select(0, &fdreads, 0, 0, 0);
            printf("select ret=%d\n", ret);
            switch(ret){
            case -1:
                perror("error");
                break;
            case 0:
                perror("timeout?");
                break;
            default:
                if(FD_ISSET(sock, &fdreads)){
                    int j = get_client();
                    printf("accept %d\n", j);
                    int len = sizeof(struct sockaddr_in);
                    clients[j] = accept(sock, 0, 0);
                    remotes[j] = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
                    addr.sin_port = htons( 0 );
                    if( bind( remotes[j], (struct sockaddr*)&addr, sizeof(struct sockaddr_in) ) < 0 )
                        exit(errno);
                    if( connect( remotes[j], (struct sockaddr*)&remote_addr, sizeof(struct sockaddr_in) ) < 0)
                        exit(errno);
                }
                for( i=0; i<client_count; i++){
                    if(!clients[i]) continue;
                    if(FD_ISSET(clients[i], &fdreads) ){
                        int ret = recv(clients[i], buf, buf_size, 0);
                        printf("client_read_ret=%d\n", ret);
                        if( ret > 0 )
                            send( remotes[i], buf, ret, 0 );
                        if( ret <= 0 )
                            remove_client(i);
                    }
                    if(FD_ISSET(remotes[i], &fdreads) ){
                        int ret = recv(remotes[i], buf, buf_size, 0);
                        printf("remote_read_ret=%d\n", ret);
                        if( ret > 0 )
                            send( clients[i], buf, ret, 0 );
                        if( ret <= 0 )
                            remove_client(i);
                    }
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    [Javascript] Data ownership, avoid accidently mutation
    [Next.js] Consume Next.js API routes with the SWR library on the client-side
    [ARIA] Read error message for the focused form field by using aria-describedby
    [ARIA] Group different DOM element in screen reader by using aria-labelledby
    [React] Handle HTTP Errors with React
    [Angular] Modify :before / :after value from Javascirpt
    [Javascript] Finding Sibling Elements
    [Javascript] Finding Parent Elements
    MAC之find与grep
    Android只播放gif动画
  • 原文地址:https://www.cnblogs.com/lexus/p/2379145.html
Copyright © 2011-2022 走看看