'Create multiple sockets on Berkeley App (Harmony3)
I'm currently working with a pic32 starter kit and i want to use it as a Berkeley server, the code above is an example part of "Harmony 3" and it works, now I'm trying to use two sockets, one for SERVERPORT 9760 and another SERVERPORT2 9650, is this possible?
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;
}
In the Harmony 3 configuration says the app has a maximum BSD sockets = 4, so there are memory available i guess, i tried copying and pasting the code in each app state (adding new elements), but only one socket works. My problem comes in this part: The second listen() returns with -1 SOCKETERROR , errno = EMFIle
`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;`
Glad if you can help me!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
