TCP server accept call does not return - tcp

We need some help with a TCP client server code. The client timesout from its connect call and the server does not return from accept. Here's the strace.
strace -p 7167 -p 7168 -p 7297
Process 7167 attached - interrupt to quit
Process 7168 attached - interrupt to quit
Process 7297 attached - interrupt to quit
[pid 7167] accept(4, <unfinished ...>
[pid 7168] accept(4, <unfinished ...>
[pid 7297] connect(3, {sa_family=AF_INET, sin_port=htons(24465), sin_addr=inet_addr("215.47.142.168")}, 16
We rebooted the system but the problem persists even immediately after reboot.
Could it be a SYN Flood problem. How do we deal with such connections? Also, do the half made connections queue up in the listen queue(argument 2 of listen call) and stop any further accepts from any client OR does the TCP some how blocks that particular client only.
Here's the code...
client.all this is inside a function that returns socket
int sock = socket(nmspace,style,protocol);
int ret;
struct hostent *hinfo;
if(sock<0){
printf("Error occurred while creating socket:%d\n",sock);
printf("%s\n",strerror(errno));
return -1;
}
memset(&dest, 0, sizeof(struct sockaddr_in));
hinfo = gethostbyname(rmserver);
if(hinfo == NULL)
printf("getbyname failed!\n");
dest.sin_family = AF_INET;
dest.sin_addr = *(struct in_addr *)(hinfo->h_addr);
dest.sin_port = htons(port);
ret = connect(sock, (struct sockaddr *)&dest, sizeof(struct sockaddr));
if(ret<0){
printf("Error occurred while connecting on the socket:%d\n",sock);
printf("%s\n",strerror(errno));
close(sock);
return -1;
}
server
making the server socket...all this is inside a function that returns the socket>>>>>>
struct sockaddr_in serv;
int mysocket,r;
mysocket = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv, 0, sizeof(struct sockaddr_in));
serv.sin_family = AF_INET;
serv.sin_addr.s_addr = INADDR_ANY;
serv.sin_port = htons(port);
r = bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr));
if(r<0) {
printf("Error occurred binding the socket:%d to the server port:%d\n",mysocket,port);
printf("%s",strerror(errno));
close(mysocket);
return -1;
}
r = listen(mysocket, 5);
if(r<0) {
printf("Error occurred while enabling listen on the socket:%d\n",mysocket);
printf("%s",strerror(errno));
close(mysocket);
return -1;
}
server accept call>>>>>>
struct sockaddr_in dest;
int socksize=sizeof(struct sockaddr_in);
int consocket;
consocket = accept(sock, (struct sockaddr *)&dest, (socklen_t *)&socksize);
if(consocket<0) {
printf("Error occurred while accepting on the socket:%d\n",sock);
printf("%s\n",strerror(errno));
}
Not using select. I hope we don't need that as the sockets are by default blocking.
cheers...raman

Your client should be using connect (man page) rather than accept. Servers use accept to accept incoming connections and to get a new socket unique to that connection, leaving the original file descriptor free for listening and accepting new connections. Clients just use the same socket after the connection is made.
Also, I recommend taking a look at how to use select (man page).

Related

ESP8266 tcp recv returning errno 11 (EAGAIN) when handling large amounts of data

I am running ESP8266_RTOS_SDK_3.4 for an app that uses TCP to talk to a private port on a local server. In normal operation, it uploads large amounts of data to the server and receives acknowledgements that are usually less than 200 bytes: this always works fine. When I do an OTA update, where it's mainly receiving data, TCP recv fails on attempting to read the first block, and errno is set to 11 (EAGAIN). Even if I make the server send just 1024 bytes, the same thing happens.
This is the TCP connect and recv code:
bool net_tcp_connect (SENDER_DESTINATION * dest) {
struct sockaddr_in destAddr;
if (!find_host (dest->hostname)) {
return false;
}
memset(&destAddr, 0, sizeof(destAddr));
memcpy (&destAddr.sin_addr, findhost_ip (), sizeof (destAddr.sin_addr));
destAddr.sin_family = AF_INET;
destAddr.sin_port = htons (dest->port);
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
LOGEF("Create: errno %d", errno);
return false;
}
struct timeval tv;
tv.tv_sec = dest->timeout;
tv.tv_usec = 0;
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv));
if (connect(sock, (struct sockaddr *)&destAddr, sizeof(destAddr)) != 0) {
LOGEF("Connect: %s %d errno %d", findhost_str (), dest->port, errno);
EVENT_HERE ( );
net_tcp_close ();
return false;
}
return true;
}
// --------------------------------------------------------------------------------------------
int net_tcp_recv (void * buffer, int max_length) {
if (sock < 0)
return false;
int bytes_received = recv (sock, buffer, max_length, 0);
if (bytes_received < 0) {
LOGEF("Receive: errno= %d", errno);
net_tcp_close ();
bytes_received = 0;
}
return bytes_received;
}
EAGAIN can be a sign of a receive timeout, but the timeout is set to 30 seconds and the server usually sends out the first 32k bytes in less than a second.
The ESP8266 code does run OK on some access points and, as far as I can tell, the same code on an ESP32 runs OK on all access points.
Any suggestions for why this might happen, or things that I could try changing in the code or the ESP setup to make it work reliably on any access point?

ESP32 TCP client

I want to set up TCP server on windows and TCP client on ESP32. Main idea is to send String to ESP32 change it and send it back to server, but I'm really new with all of this stuff and got stuck on setting up TCP client on ESP32. Examples or references would be really helpful.
int create_ipv4_socket()
{
struct addrinfo hints;
struct addrinfo *res;
struct in_addr *addr;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
int err = getaddrinfo(UDP_IPV4_ADDR, TCP_PORT, &hints, &res);
if(err != 0 || res == NULL) {
printf("DNS lookup failed err=%d res=%p\n", err, res);
return -1;
}
/* Code to print the resolved IP.
Note: inet_ntoa is non-reentrant, look at ipaddr_ntoa_r for "real" code */
addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
printf("DNS lookup succeeded. IP=%s\n", inet_ntoa(*addr));
l_sock = socket(res->ai_family, res->ai_socktype, 0);
if(l_sock < 0) {
printf("... Failed to allocate socket.\n");
freeaddrinfo(res);
return -1;
}
struct timeval to;
to.tv_sec = 2;
to.tv_usec = 0;
setsockopt(l_sock,SOL_SOCKET,SO_SNDTIMEO,&to,sizeof(to));
if(connect(l_sock, res->ai_addr, res->ai_addrlen) != 0) {
printf("... socket connect failed errno=%d\n", errno);
close(l_sock);
freeaddrinfo(res);
return -1;
}
printf("... connected\n");
freeaddrinfo(res);
// All set, socket is configured for sending and receiving
return l_sock;
}
From this forum https://www.esp32.com/viewtopic.php?t=5965
How do you communicate with your ESP? if you communicate through UART, just send him AT command he need by writing on the UART port:
"AT+CIPSTATUS\r\n"
and then wait for his response.
If you are connected to your ESP32 directly with your computer, just use putty and directly send AT command to it.
A non exhaustive list of AT's command can be found here:
https://www.espressif.com/sites/default/files/documentation/esp32_at_instruction_set_and_examples_en.pdf

Winsock server message isn't showing on client side terminal

I created a simple TCP server listening on 8080 port that sends a message to the client once a connection is established. Here's the code.
#include <iostream>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#pragma warning(disable:4996)
int main(int argc, char* argv[]) {
WSADATA wsa;
SOCKET s, new_socket;
int c;
int ret;
struct sockaddr_in server, client;
char* message = "Thank you for connecting to us but i got to go\n";
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
printf("Failed to initialize Winsock : %d", WSAGetLastError());
return 1;
}
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == INVALID_SOCKET) {
printf("Error creating socket : %d", WSAGetLastError());
}
server.sin_family = AF_INET;
server.sin_port = htons(8080);
server.sin_addr.s_addr = INADDR_ANY;
if (bind(s, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) {
printf("Error binding socket : %d\n", WSAGetLastError());
exit(EXIT_FAILURE);
}
listen(s, 3);
puts("Listening for incoming connection\n");
c = sizeof(struct sockaddr_in);
while (new_socket = accept(s, (struct sockaddr*)&client, &c) != INVALID_SOCKET) {
puts("Connection established\n");
send(new_socket, message, strlen(message), 0);
}
if (new_socket == INVALID_SOCKET) {
printf("Connection failed : %d", WSAGetLastError());
return 1;
}
closesocket(s);
WSACleanup();
return 0;
}
When I'm running this, the server runs just fine. I open another terminal and open telnet and try to connect to the server on 8080 port. This is the client side terminal.
Welcome to Microsoft Telnet Client
Escape Character is 'CTRL+]'
Microsoft Telnet> open localhost 8080
Connecting To localhost...
And this is the server side.
Listening for incoming connection
Connection established
But even after server says that a connection is established, the client side stays at "Connecting to localhost". I send the message "Thank you for connecting to us but i got to go\n" but it doesn't show on the client side. what can possibly be wrong?
As it appears, it was a silly mistake.
while (new_socket = accept(s, (struct sockaddr*)&client, &c) != INVALID_SOCKET)
Since I didn't put another bracket over the new_socket = accept(s, (struct sockaddr*)&client, &c after initializing new_socket, the inequality was being applied on the accept function return.
The correct syntax would be
while ((new_socket = accept(s, (struct sockaddr*)&client, &c)) != INVALID_SOCKET)

Winsock blocking recv() not return, while WireShark says there are incoming segments in the TCP stream

I am working with some protocol on my Windows 10 pro with VC++ 2013 Community, basically includes three steps:
client sends a GET header (e.g. authentication, etc)
server returns a HTTP header (e.g. status code 200 if everything is fine)
then server keeps sending binary data stream after the HTTP header
I send the header, and call recv() in blocking mode to receive data from server through the TCP stream. However, the recv() blocks, never return.
I use WireShark to "follow" the TCP stream, and it shows that server does keep sending binary data, and I do see ACK message from client side to acknowledge every segment it receives. However, recv() still blocks, and never returns.
I tried to use:
pure C implementation over WinSock
C# using TcpClient
C++ with Boost Asio
non-blocking WinSock (as in this article)
The first version was implemented in WinHTTP, and eventually got Timeout.
None of them can receive any data. However, the WireShark can still tell that the server keeps sending binary data.
I tried to turn off my firewall, but the problem still there.
The most weird thing is my first implementation actually did successfully get data from recv(), about two days ago. On that day, recv() returned three times, and then blocked again. The next day, the same implementation, recv() never be able to return anything.
I am really confused. Thank you!
Here is the code, blocking Winsock version:
WSADATA wsaData;
int iResult;
SOCKET ConnectSocket = INVALID_SOCKET;
struct sockaddr_in clientService;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
//----------------------
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
//----------------------
// Create a SOCKET for connecting to server
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
printf("Error at socket(): %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port of the server to be connected to.
clientService.sin_family = AF_INET;
auto ip = gethostbyname(name);
clientService.sin_addr = *(reinterpret_cast<struct in_addr *>(ip->h_addr));
clientService.sin_port = htons(DEFAULT_PORT);
//----------------------
// Connect to server.
iResult = connect(ConnectSocket, (SOCKADDR*)&clientService, sizeof(clientService));
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
printf("Unable to connect to server: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Send an initial buffer
iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0);
if (iResult == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if (iResult > 0)
printf("Bytes received: %d\n", iResult);
else if (iResult == 0)
printf("Connection closed\n");
else
printf("recv failed: %d\n", WSAGetLastError());
} while (iResult > 0);
// cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;
Since the shutdown code is a copy/paste from the microsoft page (https://msdn.microsoft.com/en-us/library/windows/desktop/ms740121(v=vs.85).aspx) - I suppose that is how they indicate sending has completed. I believe this explains the issue you're having (from the above page):
Note When issuing a blocking Winsock call such as recv, Winsock may need to wait for a network event before the call can complete. Winsock performs an alertable wait in this situation, which can be interrupted by an asynchronous procedure call (APC) scheduled on the same thread. Issuing another blocking Winsock call inside an APC that interrupted an ongoing blocking Winsock call on the same thread will lead to undefined behavior, and must never be attempted by Winsock clients.
I actually just realized that I've only ever used non-blocking sockets and always have the receiving code on its own thread. So try adding this:
iResult = ioctlsocket(m_socket, FIONBIO, &iMode);
From here:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms738573(v=vs.85).aspx
Note: You're going to get mostly a series of failed attempts to receive data from the socket - so you'll need to handle those and you'll also not want to tight loop.

Raspberry PI: endianness CROSS COMPILE

I use buildroot cross toolchain to compile Raspberry application from my computer (Ubuntu X86).
I'm developping a TCP serveur that allows a connection on 5003 (0x138B) TCP port number. When I'm start the server, that's right but my server wait a connection on 35603 (0x8B13) TCP port number (check with netstat -a).
It seems to be an endianness problem but I don't know how to resolve.
Can you help me please?
Thanks.
thanks for your answer.
I agree it's very strange. I don't think the code is the problem. It's working well on other platform.
Please find the code below:
/*Create the server */
int CreateServeur (unsigned short port, int *sock_srv, int nb_connect)
{
int l_ret = -1;
struct sockaddr_in l_srv_addr;
/* address initialisation */
printf("creation serveur port %i\n", port);
memset ((char*) &l_srv_addr,0, sizeof (struct sockaddr_in));
l_srv_addr.sin_family = PF_INET;
l_srv_addr.sin_port = port;
l_srv_addr.sin_addr.s_addr = htonl (INADDR_ANY);
/* main socket creation */
if ((*sock_srv = socket (PF_INET, SOCK_STREAM, 0)) <= 0)
{
printf("server socket creation error");
}
else
{
if (bind (*sock_srv, (struct sockaddr *) &l_srv_addr, sizeof (struct sockaddr_in)) == -1)
{
close (*sock_srv);
printf("bind socket error");
}
else
{
if (listen (*sock_srv, nb_connect) == ERROR)
{
close (*sock_srv);
printf("listen socket error");
}
else
{
l_ret = 0;
}
}
}
return (l_ret);
}
This function doesn't return any error. The first log (printf("creation serveur port %i\n", port);) display the good port (5003) but the server wait connexion on port 35603 (netstat -a).
If it's not a endianness problem, I don't understand.

Resources