Создание нескольких сокетов в приложении Berkeley (Harmony3)

В настоящее время я работаю со стартовым набором pic32 и хочу использовать его в качестве сервера Беркли, приведенный выше код является примером части «Harmony 3», и он работает, теперь я пытаюсь использовать два сокета, один для SERVERPORT 9760 и еще один SERVERPORT2 9650, это возможно?

BSD_APP_DATA berkeleyApp;

bool _APP_BsdChangeNetParam(TCPIP_NET_HANDLE netH);

void APP_BSD_Initialize(void) /* Place the Berkeley App state machine in its initial state. */ berkeleyApp.state = APP_BSD_WAIT_INIT; berkeleyApp.isDataAvailable = false; berkeleyApp.isDoneSending = false; }

void APP_BSD_Tasks() { SYS_STATUS tcpipStat; const char *netName, *netBiosName; int i, nNets; TCPIP_NET_HANDLE netH;

      switch (berkeleyApp.state)
{
case APP_BSD_WAIT_INIT:
    tcpipStat = TCPIP_STACK_Status(sysObj.tcpip);
    if (tcpipStat < 0)
    { // some error occurred
        SYS_CONSOLE_MESSAGE(" APP BSD: TCP/IP stack initialization failed!\r\n");
        berkeleyApp.state = APP_BSD_ERROR;
    }
    else if (tcpipStat == SYS_STATUS_READY)
    {
        // now that the stack is ready we can check the
        // available interfaces
        nNets = TCPIP_STACK_NumberOfNetworksGet();

        for (i = 0; i < nNets; i++)
        {

            netH = TCPIP_STACK_IndexToNet(i);
            netName = TCPIP_STACK_NetNameGet(netH);
            netBiosName = TCPIP_STACK_NetBIOSName(netH)

        }

        berkeleyApp.state = APP_BSD_WAIT_FOR_IP;
    }

    break;

case APP_BSD_WAIT_FOR_IP:
    
    nNets = TCPIP_STACK_NumberOfNetworksGet();
    for (i = 0; i < nNets; i++)
    {
        netH = TCPIP_STACK_IndexToNet(i);
        if (!TCPIP_STACK_NetIsReady(netH))
        {
            return; // interface not ready yet!
        }
        
        /* carga de la IP si la configuracion esta lista*/
        if (!APP_ConfigStatusGet())
        {
            return; // No hay datos de configuracion aun
        }
        
        if (!_APP_BsdChangeNetParam(netH))
        {
            berkeleyApp.state = APP_BSD_ERROR;
        }
    }
        
    // all interfaces ready. Could start transactions!!!
    berkeleyApp.state = APP_BSD_INIT;
    
    break;
    
case APP_BSD_INIT:

    // Initialize all client socket handles so that we don't process
    // them in the BSD_OPERATION state

    /*CLIENT SOCKETS FOR CHANNEL 1*/
    for (i = 0; i < MAX_CLIENT; i++)
        berkeleyApp.ClientSockCh1[i] = INVALID_SOCKET;


    /*CLIENT SOCKETS FOR CHANNEL 2*/
    for (i = 0; i < MAX_CLIENT; i++)
        berkeleyApp.ClientSockCh2[i] = INVALID_SOCKET;

    berkeleyApp.state = APP_BSD_CREATE_SOCKET;

    break;
        
case APP_BSD_CREATE_SOCKET:
{
    // Create a socket for this server to listen and accept connections on

    /*SOCKET FOR CHANNEL 1*/
    SOCKET tcpSkt = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (tcpSkt == INVALID_SOCKET)
        return;
    berkeleyApp.bsdServerSocketCh1 = (SOCKET) tcpSkt;
    SYS_CONSOLE_PRINT("Channel 1 Socket Created %d\r\n",tcpSkt);


    /*SOCKET FOR CHANNEL 2*/
    SOCKET tcpSkt2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (tcpSkt2 == INVALID_SOCKET)
        return;
    berkeleyApp.bsdServerSocketCh2 = (SOCKET) tcpSkt2;
    SYS_CONSOLE_PRINT("Channel 2 Socket Created %d\r\n",tcpSkt2);


    berkeleyApp.state = APP_BSD_BIND;
}
        break;
case APP_BSD_BIND:
{
    // Bind socket to a local port

    /*BIND SOCKET FOR CHANNEL 1 TO LOCAL PORT 9760*/
    struct sockaddr_in addr;
    int addrlen = sizeof (struct sockaddr_in);
    addr.sin_port = SERVER_PORT_CH1;
    addr.sin_addr.S_un.S_addr = IP_ADDR_ANY;
    int stat = bind(berkeleyApp.bsdServerSocketCh1, (struct sockaddr*) &addr, addrlen);
    if ( stat == SOCKET_ERROR)
        return;
    SYS_CONSOLE_PRINT("Channel 1 Socket Binded %d\r\n",stat);


    /*BIND SOCKET FOR CHANNEL 2 TO LOCAL PORT 9650*/
    struct sockaddr_in addr2;
    int addrlen2 = sizeof (struct sockaddr_in);
    addr2.sin_port = SERVER_PORT_CH2;
    addr2.sin_addr.S_un.S_addr = IP_ADDR_ANY;
    int stat2 = bind(berkeleyApp.bsdServerSocketCh2, (struct sockaddr*) &addr2, addrlen2);
    if ( stat2 == SOCKET_ERROR)
        return;
    SYS_CONSOLE_PRINT("Channel 2 Socket Binded %d\r\n",stat2);
    
    berkeleyApp.state = APP_BSD_LISTEN;
    // No break needed
}
    break;

case APP_BSD_LISTEN:

{
    
    /*LISTENING FOR CHANNEL 1*/
    if (listen(berkeleyApp.bsdServerSocketCh2, MAX_CLIENT) == 0) {
        SYS_CONSOLE_PRINT("Waiting for Client Connection on port: %d\r\n", SERVER_PORT_CH2);
    }
    
    
    /*LISTENING FOR CHANNEL 2*/
    int algo = listen(berkeleyApp.bsdServerSocketCh1, MAX_CLIENT);
    if ( algo == 0) {
        SYS_CONSOLE_PRINT("Waiting for Client Connection on port: %d\r\n", SERVER_PORT_CH1);
    }
    
    SYS_CONSOLE_PRINT("listen channel 2: %d",algo);
    
    berkeleyApp.state = APP_BSD_OPERATION;
}
    break;
    
case APP_BSD_OPERATION:
{
    int length;
    struct sockaddr_in addRemote;
    int addrlen = sizeof (struct sockaddr_in);
    
    berkeleyApp.isDoneSending = false;   

    for (i = 0; i < MAX_CLIENT; i++)
    {
        // Accept any pending connection requests, assuming we have a place to store the socket descriptor
        if (berkeleyApp.ClientSockCh1[i] == INVALID_SOCKET)
            berkeleyApp.ClientSockCh1[i] = accept(berkeleyApp.bsdServerSocketCh1, (struct sockaddr*) &addRemote, &addrlen);
        
        // If this socket is not connected then no need to process anything
        if (berkeleyApp.ClientSockCh1[i] == INVALID_SOCKET)
            continue;

        // For all connected sockets, receive and send back the data
        length = recv(berkeleyApp.ClientSockCh1[i], berkeleyApp.rxBuffer, sizeof (berkeleyApp.rxBuffer), 0);
        if (length > 0)
        {
            berkeleyApp.rxBuffer[length] = '\0';
            berkeleyApp.state = APP_BSD_WAIT_USART_RECEIVE_DATA;
            berkeleyApp.isDataAvailable = true;
            berkeleyApp.channels = CHANNEL1;
            berkeleyApp.socket = i;
            APP_UsartWriteBuffer(berkeleyApp.rxBuffer);
            
            
            #ifdef DEBUG
            SYS_CONSOLE_PRINT("BklR <%s> <sck:%d>\n\r",berkeleyApp.rxBuffer,berkeleyApp.socket);
            #endif
            
        }
        else if (length == 0 || errno != EWOULDBLOCK)
        {
            closesocket(berkeleyApp.ClientSockCh1[i]);
            berkeleyApp.ClientSockCh1[i] = INVALID_SOCKET;
        }
        // else just wait for some more data
    }
    
    for (i = 0; i < MAX_CLIENT; i++)
    {
        // Accept any pending connection requests, assuming we have a place to store the socket descriptor
        if (berkeleyApp.ClientSockCh2[i] == INVALID_SOCKET)
            berkeleyApp.ClientSockCh2[i] = accept(berkeleyApp.bsdServerSocketCh2, (struct sockaddr*) &addRemote, &addrlen);
        
        // If this socket is not connected then no need to process anything
        if (berkeleyApp.ClientSockCh2[i] == INVALID_SOCKET)
            continue;

        // For all connected sockets, receive and send back the data
        length = recv(berkeleyApp.ClientSockCh2[i], berkeleyApp.rxBuffer, sizeof (berkeleyApp.rxBuffer), 0);
        if (length > 0)
        {
            berkeleyApp.rxBuffer[length] = '\0';
            berkeleyApp.state = APP_BSD_WAIT_USART_RECEIVE_DATA;
            berkeleyApp.isDataAvailable = true;
            berkeleyApp.channels = CHANNEL2;
            berkeleyApp.socket = i;
            APP_UsartWriteBuffer(berkeleyApp.rxBuffer);
            
            
            #ifdef DEBUG
            SYS_CONSOLE_PRINT("BklR <%s> <sck:%d>\n\r",berkeleyApp.rxBuffer,berkeleyApp.socket);
            #endif
            
        }
        else if (length == 0 || errno != EWOULDBLOCK)
        {
            closesocket(berkeleyApp.ClientSockCh2[i]);
            berkeleyApp.ClientSockCh2[i] = INVALID_SOCKET;
        }
        // else just wait for some more data
    }
    
    // Pregunta por cambios en la configuracion de red
    if (APP_ConfigNetChangeGet() || APP_DefaultConfigNetChangeGet())  
    {
        // cierra socket por seguridad solamente
        
        if (berkeleyApp.channels == CHANNEL1)
        {
            closesocket(berkeleyApp.ClientSockCh1[i]);
            berkeleyApp.ClientSockCh1[i] = INVALID_SOCKET;
        }
        
        closesocket(berkeleyApp.ClientSockCh2[i]);
        berkeleyApp.ClientSockCh2[i] = INVALID_SOCKET;

        // limpia banderas de cambio de configuracion y cambia estado para recargar parametros de red
        APP_ConfigNetChangeClear();
        APP_DefaultConfigNetChangeClear();

        netH = TCPIP_STACK_IndexToNet(0);
        if (!_APP_BsdChangeNetParam(netH))
        {
            berkeleyApp.state = APP_BSD_ERROR;
        }
    }

    break;
}
case APP_BSD_WAIT_USART_RECEIVE_DATA:
{  
    if (APP_UsartTransferStatusGet())
    {
        #ifdef DEBUG
        SYS_CONSOLE_PRINT("BklS <%s> <%d>\n\r", berkeleyApp.txBuffer,strlen(berkeleyApp.txBuffer));
        #endif
        APP_UsartReadBuffer(berkeleyApp.txBuffer);
        
        if(berkeleyApp.channels == CHANNEL1)
        {
            send(berkeleyApp.ClientSockCh1[berkeleyApp.socket], berkeleyApp.txBuffer, strlen(berkeleyApp.txBuffer), 0);
        }
        send(berkeleyApp.ClientSockCh2[berkeleyApp.socket], berkeleyApp.txBuffer, strlen(berkeleyApp.txBuffer), 0);
        berkeleyApp.isDoneSending = true;   
        berkeleyApp.isDataAvailable = false;
        berkeleyApp.state = APP_BSD_OPERATION;
    }
    
    break;
}
case APP_BSD_ERROR:
    
    break;
default:
    break;
}

В конфигурации Harmony 3 говорится, что приложение имеет максимальное количество сокетов BSD = 4, поэтому, я думаю, есть доступная память, я пытался копировать и вставлять код в каждое состояние приложения (добавляя новые элементы), но работает только один сокет. Моя проблема возникает в этой части: второй listen() возвращает с -1 SOCKETERROR , errno = EMFIle

`случай APP_BSD_LISTEN:

      {
    
    /*LISTENING FOR CHANNEL 1*/
    if (listen(berkeleyApp.bsdServerSocketCh2, MAX_CLIENT) == 0) {
        SYS_CONSOLE_PRINT("Waiting for Client Connection on port: %d\r\n", SERVER_PORT_CH2);
    }
    
    
    /*LISTENING FOR CHANNEL 2*/
    int algo = listen(berkeleyApp.bsdServerSocketCh1, MAX_CLIENT);
    if ( algo == 0) {
        SYS_CONSOLE_PRINT("Waiting for Client Connection on port: %d\r\n", SERVER_PORT_CH1);
    }
    
    SYS_CONSOLE_PRINT("listen channel 2: %d",algo);
    
    berkeleyApp.state = APP_BSD_OPERATION;
}
    break;`

Рад, если вы можете мне помочь!

0 ответов

Другие вопросы по тегам