We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi
I'm trying to implement non-blocking BDS sockets TCP server. I will not allow use of multiple clients. I'm using Keil 4.74 with Real Time OS.
Socket is in blocking mode until client connection request is accepted. After that, socket mode is set to non-blocking.
Server must replay to every client request. Events generated on server side are being immediately sent to connected client.
I must restart my demo board or perform reset with debugger to fix problem. When problem occurs, I can connect to server, but I'll not get response from server. TCP disconect seems OK in Wireshark.
Problem occurs while performin bind(). I'm receiving error code -3 (SCK_EINVALIDPARA). I've tested code with TCP debug library and I'm getting BSD SOCKET PORT IN USE error.
I've tried set socket to non-blocking immediately after socket() function, but this doesn't fix problem.
__task void bsd_tcp_server(void) { SOCKADDR_IN addr; unsigned long sck_mode = 1;
int32_t sock, sd, res; char buf[256];
while (1) { if ((sock = socket (AF_INET, SOCK_STREAM, 0)) > 0) { addr.sin_port = htons(1000); addr.sin_family = PF_INET; addr.sin_addr.s_addr = INADDR_ANY;
if ((res = bind(sock, (SOCKADDR *)&addr, sizeof(addr))) == SCK_SUCCESS) { if ((res = listen(sock, 1)) == SCK_SUCCESS) { sd = accept(sock, NULL, NULL); closesocket(sock);
if (sd > 0) { sock = sd;
if (ioctlsocket (sock, FIO_DELAY_ACK, &sck_mode) == SCK_SUCCESS) { if (ioctlsocket (sock, FIONBIO, &sck_mode) == SCK_SUCCESS) { while (1) { res = recv(sock, buf, sizeof(buf), 0);
if ((res <= 0) && (res != SCK_EWOULDBLOCK) && (res!=SCK_ELOCKED)) { break; }
else if (res > 0) { // analyse request, send response // if send() returns error, close socket if (analyse_response(sock, (uint8_t *) buf, res) < 0) { close_nonblocking_socket(sock); break; } }
os_dly_wait(25);
// if there is pending event, perform send() // if send() returns error, close socket if (send_status_update(sock) < 0) { close_nonblocking_socket(sock); break; } } } } } } }
closesocket(sock); } os_dly_wait(25); } }
__task void bsd_tcp_server(void) { SOCKADDR_IN addr; unsigned long sck_mode = 1; int32_t sock, sd, res; char buf[256]; while (1) { if ((sock = socket (AF_INET, SOCK_STREAM, 0)) > 0) { addr.sin_port = htons(1000); addr.sin_family = PF_INET; addr.sin_addr.s_addr = INADDR_ANY; if ((res = bind(sock, (SOCKADDR *)&addr, sizeof(addr))) == SCK_SUCCESS) { if ((res = listen(sock, 1)) == SCK_SUCCESS) { sd = accept(sock, NULL, NULL); closesocket(sock); if (sd > 0) { sock = sd; if (ioctlsocket (sock, FIO_DELAY_ACK, &sck_mode) == SCK_SUCCESS) { if (ioctlsocket (sock, FIONBIO, &sck_mode) == SCK_SUCCESS) { while (1) { res = recv(sock, buf, sizeof(buf), 0); if ((res <= 0) && (res != SCK_EWOULDBLOCK) && (res!=SCK_ELOCKED)) { break; } else if (res > 0) { // analyse request, send response // if send() returns error, close socket if (analyse_response(sock, (uint8_t *) buf, res) < 0) { close_nonblocking_socket(sock); break; } } os_dly_wait(25); // if there is pending event, perform send() // if send() returns error, close socket if (send_status_update(sock) < 0) { close_nonblocking_socket(sock); break; } } } } } } } closesocket(sock); } os_dly_wait(25); } }
Socket close function also needs time to complete. When the socket is in non-blocking mode, the function closesocket() needs additional calls until the function returns SCK_SUCCESS.