Создание нескольких сокетов в приложении 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;`
Рад, если вы можете мне помочь!