Windows 7 upgrade, UDP Broadcast issue - networking

I am new to this environment as far as UDP protocols and sending/receiving data via networks. I have read the other post regarding this kind of issue but I am not sure how to fix my problem:
I have just upgraded a PC to Windows 7 from XP. This upgrade was due to my application needs to run on Win7. I have NOT changed the was our UDP stream is broadcasted. With the upgrade I can no longer run the older version of my application becasue the UDP stream doesn't seam to get to my application.
I have turned off all firewalls and am running everything as admin.
This is how my setup is:
Code is running on ip: 192.168.2.1
UDP is sent from 192.168.2.1 to 192.168.2.87 and then broadcasted to 192.168.2.255
I used to be able to see this UDP stream with my old application on a seperate computer: 192.168.2.12
If I change my UDP stream to go directly to 192.168.2.12 ip, then my application works, but then the UDP is not broadcasted anymore. I need the UDP to be able to be read by more than one computer.
Here is my wireshark out put for the UDP Stream:
Source: 192.168.2.87
Destination: 192.168.2.255
Protocol: UDP Info:
Sorce Port: 6601 Destination Port: 6601
I have tried hard coding my c-code to listen to any possibility I can think of, aka the sender addr function:
senderAddr.sin_addr.s_addr = htonl(INADDR_ANY);
To something like:
senderAddr.sin_addr.s_addr = inet_addr("192.168.2.212")
This is the code to init the I/O buffer:
// UDP Receiver Declarations -
SOCKET SockIn = INVALID_SOCKET;
SOCKADDR_IN senderAddr;
int senderSize = sizeof(senderAddr);
u_short PortIn = 6601;
int timeout = 1;
//===================<Callbacks::Callbacks>==================
//
// Summary: Constructor
//
//=============================================================================
Callbacks::Callbacks(RTUserIntegrationI &a_rIntegration)
: m_rIntegration(a_rIntegration)
, m_pUDPInput(NULL)
{
}
//=====================<Callbacks::~Callbacks>===============
//
// Summary: Destructor
//
//=============================================================================
Callbacks::~Callbacks()
{
}
//=====================<Callbacks::InitIOBuffers>====================
//
// Summary: Init function for the IO buffer
//
//=============================================================================
void Callbacks::vInitIOBuffers()
{
BOOL bOptVal = TRUE;
int bOptLen = sizeof(BOOL);
WSADATA WSAData;
UInt Size = 0;
// UDP Declarations -
// Initialize the member pointers to buffers
bufferin = m_rIntegration.pGetIOBuffer(Input_Buffer);
if (bufferin != NULL)
m_pUDPInput = static_cast<InputData*>(bufferin->pGetDataAddress(Size));
// UDP Receive -
if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)
{
printf("\nCould not open WSA connection");
WSACleanup();
}
SockIn = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (SockIn == INVALID_SOCKET)
{
printf("\nCould not create socket.");
closesocket(SockIn);
WSACleanup();
}
senderAddr.sin_family = AF_INET;
senderAddr.sin_port = htons(PortIn);
senderAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (setsockopt(SockIn, SOL_SOCKET, SO_REUSEADDR, (char*)&bOptVal, bOptLen) != INVALID_SOCKET)
{
printf("\nSet SO_REUSEADDR: ON.");
}
if (bind(SockIn, (struct sockaddr *) &senderAddr, senderSize) == -1)
{
printf("\nCould not bind socket.");
closesocket(SockIn);
WSACleanup();
}
setsockopt(SockIn, SOL_SOCKET, SO_RCVTIMEO, (char*) &timeout, sizeof(timeout));
}
I have the receive port number hard coded to 6601.
The code above works fine and the computer sees and reads the broadcasted UDP in Windows XP but ceases to work in Windows 7.
Any suggestions would be greatly appreciated.
ADDED:
192.168.2.1 generates the UDP stream--->sent to 192.168.2.87---> broadcasted on 192.168.2.255 ---> Notheing has changed on any of those computers....... I then have two computers (one XP and one Windows 7) than listen to the 2.255 ip. XP is getting the UDP and Win7 is not.

Related

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 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.

Microchip TCPIP keep alive not works

i'm trying to build a server with a PIC24F.
This is a piece of code i'm isuing:
switch(TCPServerState) {
case SM_HOME:
// Allocate a socket for this server to listen and accept connections on
socket.Socket = TCPOpen(0, TCP_OPEN_SERVER, SERVER_PORT, TCP_PURPOSE_GENERIC_TCP_SERVER);
if(socket.Socket != INVALID_SOCKET) {
TCPServerState = SM_LISTENING;
}
break;
case SM_LISTENING:
// See if anyone is connected to us
//if(TCPIsConnected(socket.Socket)) {
if(!TCPWasReset(socket.Socket)){
if(socket.Connected == 0) {
socket.Connected = 1;
printf("Socket is CONNECTED: %d\n", socket.Socket);
}
uint16_t avaible = TCPIsGetReady(socket.Socket);
// Some stuff
}
else if(socket.Connected == 1){
printf("Socket RESET: %d\n", socket.Socket);
TCPServerState = SM_CLOSING;
}
break;
case SM_CLOSING:
// Close the socket connection.
socket.Connected = 0;
TCPClose(socket.Socket);
TCPServerState = SM_HOME;
printf("Socket is CLOSED: %d\n", socket.Socket);
break;
}
All works fine if i close my client socket properly, but if i disconnect ethernet cable i am not able to detect disconnection and my code does not close the socket because TCPWasReset still FALSE(or TCPIsConnected still TRUE).
So how can i detect the disconnection of network cable(without add a software keep_alive implementation) ?
Thanks
Check a few items:
Call TickInit(); before StackInit();
Select the correct TIMER1 clock source for your application - internal clock or external clock (T1CON.TCS)
Otherwise, just use a debugger on the keepalive logic in TCP.C, which should default to 10 seconds in the latest Microchip Library for Applications TCP/IP stack 5.42.08.

Problem in listening to multicast in C++ with multiple NICs

I am trying to write a multicast client on a machine with two NICs, and I can't make it work. I can see with a sniffer that once I start the program the NIC (eth4) start receiving the multicast datagrams, However, I can't recieve() any in my program.
When running "tshark -i eth4 -R udp.port==xxx (multicast port)"
I get:
1059.435483 y.y.y.y. (some ip) -> z.z.z.z (multicast ip, not my eth4 NIC IP) UDP Source port: kkk (some other port) Destination port: xxx (multicast port)
Searched the web for some examples/explanations, but it seems like I do what everybody else does. Any help will be appreciated. (anything to do with route/iptables/code?)
bool connectionManager::sendMulticastJoinRequest()
{
struct sockaddr_in localSock;
struct ip_mreqn group;
char* mc_addr_str = SystemManager::Instance()->getTCP_IP_CHT();
char* local_addr_str = SystemManager::Instance()->getlocal_IP_TOLA();
int port = SystemManager::Instance()->getTCP_Port_CHT();
/* Create a datagram socket on which to receive. */
CHT_UDP_Feed_sock = socket(AF_INET, SOCK_DGRAM, 0);
if(CHT_UDP_Feed_sock < 0)
{
perror("Opening datagram socket error");
return false;
}
/* application to receive copies of the multicast datagrams. */
{
int reuse = 1;
if(setsockopt(CHT_UDP_Feed_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0)
{
perror("Setting SO_REUSEADDR error");
close(CHT_UDP_Feed_sock);
return false;
}
}
/* Bind to the proper port number with the IP address */
/* specified as INADDR_ANY. */
memset((char *) &localSock, 0, sizeof(localSock));
localSock.sin_family = AF_INET;
localSock.sin_port = htons(port);
localSock.sin_addr.s_addr =inet_addr(local_addr_str); // htonl(INADDR_ANY); //
if(bind(CHT_UDP_Feed_sock, (struct sockaddr*)&localSock, sizeof(localSock)))
{
perror("Binding datagram socket error");
close(CHT_UDP_Feed_sock);
return false;
}
/* Join the multicast group mc_addr_str on the local local_addr_str */
/* interface. Note that this IP_ADD_MEMBERSHIP option must be */
/* called for each local interface over which the multicast */
/* datagrams are to be received. */
group.imr_ifindex = if_nametoindex("eth4");
if (setsockopt(CHT_UDP_Feed_sock, SOL_SOCKET, SO_BINDTODEVICE, "eth4", 5) < 0)
return false;
group.imr_multiaddr.s_addr = inet_addr(mc_addr_str);
group.imr_address.s_addr = htonl(INADDR_ANY); //also tried inet_addr(local_addr_str); instead
if(setsockopt(CHT_UDP_Feed_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group)) < 0)
{
perror("Adding multicast group error");
close(CHT_UDP_Feed_sock);
return false;
}
// Read from the socket.
char databuf[1024];
int datalen = sizeof(databuf);
if(read(CHT_UDP_Feed_sock, databuf, datalen) < 0)
{
perror("Reading datagram message error");
close(CHT_UDP_Feed_sock);
return false;
}
else
{
printf("Reading datagram message...OK.\n");
printf("The message from multicast server is: \"%s\"\n", databuf);
}
return true;
}
Just a thought, (I've not done much work with multicast), but could it be because you're binding to a specific IP address? The socket could be only accepting packets destined for it's bound IP address and rejecting the multicast ones?
Well, there is some time ago since I didn't play with multicast. Don't you need root/admin rights to use it? did you enable them when launching your program?

Resources