FreeRTOS + LWIP -UDP Data Transfer - udp

I am kinda new to the lwip stack. I'm trying to send some data over UDP protocol from my development board to my pc. And using ethernet cable between the two of them.
I gave an ip address to my server(source-board), which is 192.168.1.75:88. And the ip address of my computer is 192.168.1.2:90. When I set this configuration and run the program, I can sniff nothing with wireshark, I mean there is no udp package exchange at all. But when I change all destination adress to 255.255.255.255 or 0.0.0.0, I can sniff some packages.
Why can't I send udp packages to the ip address that I want?
Main.c
int main(void)
{
#define dst_port 88
#define src_port 90
#ifdef SERIAL_DEBUG
DebugComPort_Init();
#endif
LCD_LED_Init();
ETH_BSP_Config();
LwIP_Init();
IP4_ADDR(&dstaddr, 0, 0, 0, 0);
IP4_ADDR(&srcaddr, 192, 168, 1, 75);
pcb = udp_new();
udp_bind(pcb, &dstaddr, src_port);
udp_recv(pcb, RecvUTPCallBack, NULL);
udp_connect(pcb, &dstaddr, dst_port);
#ifdef USE_DHCP
/* Start DHCPClient */
xTaskCreate(LwIP_DHCP_task, "DHCPClient", configMINIMAL_STACK_SIZE * 2, NULL,DHCP_TASK_PRIO, NULL);
#endif
/* Start toogleLed4 task : Toggle LED4 every 250ms */
xTaskCreate(ToggleLed4, "LED4", configMINIMAL_STACK_SIZE, NULL, LED_TASK_PRIO, NULL);
xTaskCreate(SendUDP, "UDP", configMINIMAL_STACK_SIZE, NULL, LED_TASK_PRIO, NULL);
/* Start scheduler */
vTaskStartScheduler();
for( ;; );
}
SendUDP Task
void SendUDP(void * pvParameters)
{
while(1)
{
pcb = udp_new();
udp_bind(pcb, &dstaddr, src_port);
udp_recv(pcb, RecvUTPCallBack, NULL);
udp_connect(pcb, &dstaddr, dst_port);
pb = pbuf_alloc(PBUF_TRANSPORT, sizeof((str)), PBUF_REF);
pb->payload = str;
pb->len = pb->tot_len = sizeof((str));
udp_sendto(pcb, pb, &dstaddr, dst_port);
udp_disconnect(pcb);
udp_remove(pcb);
pbuf_free(pb);
vTaskDelay(1000);
}
}

I figured this out about a week ago, but I couldn't post the answer to here.
First of all, there is an ip defining in main.h, like
/*Static IP ADDRESS*/
#define IP_ADDR0 192
#define IP_ADDR1 168
#define IP_ADDR2 1
#define IP_ADDR3 15
and this configurations being use in netconf.h
IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
that's why server's ip adress is always 192.168.1.15.
And the second, I just started to use netconn API instead of raw API, this is way much easier than raw API. And this is my new SendwithUDP function, which is working perfect.
void SendwithUDP(uint16_t *veri, uint8_t length)
{
while(1)
{
if(((EventFlags.udp) && (1<<0)) == (1<<0))
{
STM_EVAL_LEDToggle(LED3);
sendconn = netconn_new( NETCONN_UDP );
netconn_bind(sendconn, IP_ADDR_ANY, src_port );
netconn_connect(sendconn, &clientAddr, 150);
sendbuf = netbuf_new();
data =netbuf_alloc(sendbuf, 2*length);
memcpy(data, veri, 2*length);
netconn_send(sendconn, sendbuf);
netbuf_free(sendbuf);
netbuf_delete(sendbuf);
netconn_disconnect(sendconn);
netconn_delete(sendconn);
vTaskDelay(10);
}
}
}

Related

STM32 - Can't receive msg from multicast address

I have a client/server LWIP program, I want to use multicast features so I used IGMP library did the following setting like this:
Setting .IOC
Enable LWIP_IGMP
Enable LWIP_MULTICAST_TX_OPTION
Enable LWIP_IP4
in ethernet.c
netif->flags |= NETIF_FLAG_IGMP
in stm32f7xx_hal_eth.c (ETH_MACDMAConfig)
macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_ENABLE;
macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_NONE;
and i implemented code like this :
void UDP_Multicast_init(void *arg)
{
struct ip4_addr ipgroup, localIP;
struct udp_pcb *upcb;
char msg[] = "hello";
struct pbuf* p;
p = pbuf_alloc(PBUF_TRANSPORT,sizeof(msg),PBUF_RAM);
memcpy (p->payload, msg, sizeof(msg));
IP4_ADDR(&ipgroup, 224, 224, 0, 1); //Multicast IP address.
IP4_ADDR(&localIP, 192, 168, 1, 99); //Interface IP address
#if LWIP_IGMP
igmp_joingroup((ip4_addr_t *)(&localIP),(ip4_addr_t *)(&ipgroup));
#endif
upcb = ( struct udp_pcb*) udp_new();
MulticastStart(); //binding connection to the port 10
udp_recv(upcb, UDP_callback, NULL);
udp_sendto(upcb,p,&ipgroup,10);
}
void UDP_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p,
const ip_addr_t *addr, u16_t port)
{
printf("test");
}
and I try to see in wireshark, iplocal successfully joins into the multicast address, and sends a data to the multicast address.
enter image description here
but the callback function cannot be executed.
is there something missing??
thanks for the response.

How to receive data over Ethernet using LWIP, UDP

I'm trying to send data to and from my computer and an STM32H745 over Ethernet using LwIP and UDP. I have successfully configured the card and right now I can send data from the card to a Python script running on the computer. However, I don't understand how udp_recv works <udp,lwip> or how to receive data with UDP on LwIP in general, and I can't find examples that do just that. Where is the data being received? Should I even use udp_recv?
In the main loop I run MX_LWIP_Process, which runs ethernetif_input which somehow handles the received data, but I don't understand where it puts it.
Below is the main code, just for reference.
const char* message = "a";
HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_1); // orange
ip_addr_t PC_IPADDR;
IP_ADDR4(&PC_IPADDR, 192, 168, 1, 200);
u16_t port = 8000;
struct udp_pcb* my_udp = udp_new();
struct pbuf* udp_buffer = NULL;
/* Infinite loop */
for (;; )
{
MX_LWIP_Process();
HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_1); // orange
HAL_Delay(1000);
udp_buffer = pbuf_alloc(PBUF_TRANSPORT, strlen(message), PBUF_RAM);
if (udp_buffer != NULL)
{
memcpy(udp_buffer->payload, message, strlen(message));
udp_sendto(my_udp, udp_buffer,&PC_IPADDR, port);
pbuf_free(udp_buffer);
}
//udp_recv (struct udp_pcb *pcb, udp_recv_fn recv, void *recv_arg)
}
udp_recv() does not actually receive UDP datagrams (despite its name). It registers a callback function that will then be called by MX_LWIP_Process() when a datagram has been buffered. It would better be called udp_set_recv_callback(), but it is what it is.
To that end you should call it once before your executive loop:
udp_bind( my_udp, IP_ADDR_ANY, port ) ;
udp_recv( my_udp, udp_receive_callback, NULL ) ;
/* Infinite loop */
for (;; )
{
// Run the CubeMX LwIP stack
MX_LWIP_Process() ;
...
}
Where udp_receive_callback is a function that will be invoked on receipt of a datagram:
void udp_receive_callback( void* arg, // User argument - udp_recv `arg` parameter
struct udp_pcb* upcb, // Receiving Protocol Control Block
struct pbuf* p, // Pointer to Datagram
const ip_addr_t* addr, // Address of sender
u16_t port ) // Sender port
{
// Process datagram here (non-blocking code)
...
// Must free receive pbuf before return
pbuf_free(p);
}
Examples include:
https://gist.github.com/iwanbk/1399729
https://github.com/STMicroelectronics/STM32CubeF2/blob/master/Projects/STM322xG_EVAL/Applications/LwIP/LwIP_UDP_Echo_Client/Src/udp_echoclient.c
Documentation can be found at https://www.nongnu.org/lwip/2_0_x/group__udp__raw.html

How to put BG96 on power save mode between sending messages to Azure IoT Hub over HTTP

I'm using a Nucleo L496ZG, X-NUCLEO-IKS01A2 and the Quectel BG96 module to send sensor data (temperature, humidity etc..) to Azure IoT Central over HTTP.
I've been using the example implementation provided by Avnet here, which works fine but it's not power optimized and with a 6700mAh battery pack it only lasts around 30 hours sending telemetry ever ~10 seconds. Goal is for it to last around a week. I'm open to increasing the time between messages but I also want to save power in between sending.
I've gone over the Quectel BG96 manuals and I've tried two things:
1) powering off the device by driving the PWRKEY and turning it back on when I need to send a message
I've gotten this to work, kinda… until I get a hardfault exception which happens seemingly randomly anywhere from within ~5 minutes of running to 2 hours (messages successfully sending prior to the exception). Output of crash log parser is the same every time:
Crash location = strncmp [0x08038DF8] (based on PC value)
Caller location = _findenv_r [0x0804119D] (based on LR value)
Stack Pointer at the time of crash = [20008128]
Target and Fault Info:
Processor Arch: ARM-V7M or above
Processor Variant: C24
Forced exception, a fault with configurable priority has been escalated to HardFault
A precise data access error has occurred. Faulting address: 03060B30
The caller location traces back to my .map file and I don't know what to make of it.
My code:
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//#define USE_MQTT
#include <stdlib.h>
#include "mbed.h"
#include "iothubtransporthttp.h"
#include "iothub_client_core_common.h"
#include "iothub_client_ll.h"
#include "azure_c_shared_utility/platform.h"
#include "azure_c_shared_utility/agenttime.h"
#include "jsondecoder.h"
#include "bg96gps.hpp"
#include "azure_message_helper.h"
#define IOT_AGENT_OK CODEFIRST_OK
#include "azure_certs.h"
/* initialize the expansion board && sensors */
#include "XNucleoIKS01A2.h"
static HTS221Sensor *hum_temp;
static LSM6DSLSensor *acc_gyro;
static LPS22HBSensor *pressure;
static const char* connectionString = "xxx";
// to report F uncomment this #define CTOF(x) (((double)(x)*9/5)+32)
#define CTOF(x) (x)
Thread azure_client_thread(osPriorityNormal, 10*1024, NULL, "azure_client_thread");
static void azure_task(void);
EventFlags deleteOK;
size_t g_message_count_send_confirmations;
/* create the GPS elements for example program */
BG96Interface* bg96Interface;
//static int tilt_event;
// void mems_int1(void)
// {
// tilt_event++;
// }
void mems_init(void)
{
//acc_gyro->attach_int1_irq(&mems_int1); // Attach callback to LSM6DSL INT1
hum_temp->enable(); // Enable HTS221 enviromental sensor
pressure->enable(); // Enable barametric pressure sensor
acc_gyro->enable_x(); // Enable LSM6DSL accelerometer
//acc_gyro->enable_tilt_detection(); // Enable Tilt Detection
}
void powerUp(void) {
if (platform_init() != 0) {
printf("Error initializing the platform\r\n");
return;
}
bg96Interface = (BG96Interface*) easy_get_netif(true);
}
void BG96_Modem_PowerOFF(void)
{
DigitalOut BG96_RESET(D7);
DigitalOut BG96_PWRKEY(D10);
DigitalOut BG97_WAKE(D11);
BG96_RESET = 0;
BG96_PWRKEY = 0;
BG97_WAKE = 0;
wait_ms(300);
}
void powerDown(){
platform_deinit();
BG96_Modem_PowerOFF();
}
//
// The main routine simply prints a banner, initializes the system
// starts the worker threads and waits for a termination (join)
int main(void)
{
//printStartMessage();
XNucleoIKS01A2 *mems_expansion_board = XNucleoIKS01A2::instance(I2C_SDA, I2C_SCL, D4, D5);
hum_temp = mems_expansion_board->ht_sensor;
acc_gyro = mems_expansion_board->acc_gyro;
pressure = mems_expansion_board->pt_sensor;
azure_client_thread.start(azure_task);
azure_client_thread.join();
platform_deinit();
printf(" - - - - - - - ALL DONE - - - - - - - \n");
return 0;
}
static void send_confirm_callback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback)
{
//userContextCallback;
// When a message is sent this callback will get envoked
g_message_count_send_confirmations++;
deleteOK.set(0x1);
}
void sendMessage(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, char* buffer, size_t size)
{
IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromByteArray((const unsigned char*)buffer, size);
if (messageHandle == NULL) {
printf("unable to create a new IoTHubMessage\r\n");
return;
}
if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messageHandle, send_confirm_callback, NULL) != IOTHUB_CLIENT_OK)
printf("FAILED to send! [RSSI=%d]\n", platform_RSSI());
else
printf("OK. [RSSI=%d]\n",platform_RSSI());
IoTHubMessage_Destroy(messageHandle);
}
void azure_task(void)
{
//bool tilt_detection_enabled=true;
float gtemp, ghumid, gpress;
int k;
int msg_sent=1;
while (true) {
powerUp();
mems_init();
/* Setup IoTHub client configuration */
IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString, HTTP_Protocol);
if (iotHubClientHandle == NULL) {
printf("Failed on IoTHubClient_Create\r\n");
return;
}
// add the certificate information
if (IoTHubClient_LL_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
printf("failure to set option \"TrustedCerts\"\r\n");
#if MBED_CONF_APP_TELUSKIT == 1
if (IoTHubClient_LL_SetOption(iotHubClientHandle, "product_info", "TELUSIOTKIT") != IOTHUB_CLIENT_OK)
printf("failure to set option \"product_info\"\r\n");
#endif
// polls will happen effectively at ~10 seconds. The default value of minimumPollingTime is 25 minutes.
// For more information, see:
// https://azure.microsoft.com/documentation/articles/iot-hub-devguide/#messaging
unsigned int minimumPollingTime = 9;
if (IoTHubClient_LL_SetOption(iotHubClientHandle, "MinimumPollingTime", &minimumPollingTime) != IOTHUB_CLIENT_OK)
printf("failure to set option \"MinimumPollingTime\"\r\n");
IoTDevice* iotDev = (IoTDevice*)malloc(sizeof(IoTDevice));
if (iotDev == NULL) {
return;
}
setUpIotStruct(iotDev);
char* msg;
size_t msgSize;
hum_temp->get_temperature(&gtemp); // get Temp
hum_temp->get_humidity(&ghumid); // get Humidity
pressure->get_pressure(&gpress); // get pressure
iotDev->Temperature = CTOF(gtemp);
iotDev->Humidity = (int)ghumid;
iotDev->Pressure = (int)gpress;
printf("(%04d)",msg_sent++);
msg = makeMessage(iotDev);
msgSize = strlen(msg);
sendMessage(iotHubClientHandle, msg, msgSize);
free(msg);
iotDev->Tilt &= 0x2;
/* schedule IoTHubClient to send events/receive commands */
IOTHUB_CLIENT_STATUS status;
while ((IoTHubClient_LL_GetSendStatus(iotHubClientHandle, &status) == IOTHUB_CLIENT_OK) && (status == IOTHUB_CLIENT_SEND_STATUS_BUSY))
{
IoTHubClient_LL_DoWork(iotHubClientHandle);
ThisThread::sleep_for(100);
}
deleteOK.wait_all(0x1);
free(iotDev);
IoTHubClient_LL_Destroy(iotHubClientHandle);
powerDown();
ThisThread::sleep_for(300000);
}
return;
}
I know PSM is probably the way to go since powering on/off the device draws a lot of power but it would be useful if someone had an idea of what is happening here.
2) putting the device to PSM between sending messages
The BG96 library in the example code I'm using doesn't have a method to turn on PSM so I tried to implement my own. When I tried to run it, it basically runs into an exception right away so I know it's wrong (I'm very new to embedded development and have no prior experience with AT commands).
/** ----------------------------------------------------------
* this is a method provided by current library
* #brief Tx a string to the BG96 and wait for an OK response
* #param none
* #retval true if OK received, false otherwise
*/
bool BG96::tx2bg96(char* cmd) {
bool ok=false;
_bg96_mutex.lock();
ok=_parser.send(cmd) && _parser.recv("OK");
_bg96_mutex.unlock();
return ok;
}
/**
* method I created in an attempt to use PSM
*/
bool BG96::psm(void) {
return tx2bg96((char*)"AT+CPSMS=1,,,”00000100”,”00000001”");
}
Can someone tell me what I'm doing wrong and provide any guidance on how I can achieve my goal of having my device run on battery for longer?
Thank you!!
I got Power Saving Mode working by using Mbed's ATCmdParser and the AT+QPSMS commands as per Quectel's docs. The modem doesn't always go into power saving mode right away so that should be noted. I also found that I have to restart the modem afterwards or else I get weird behaviour. My code looks something like this:
bool BG96::psm(char* T3412, char* T3324) {
_bg96_mutex.lock();
if(_parser.send("AT+QPSMS=1,,,\"%s\",\"%s\"", T3412, T3324) && _parser.recv("OK")) {
_bg96_mutex.unlock();
}else {
_bg96_mutex.unlock();
return false;
}
return BG96Ready(); }//restarts modem
To send a message to Azure, the modem will need to be manually woken up by driving the PWRKEY to start bi-directional communication, and a new client handle needs to be created and torn down every time since Azure connection uses keepAlive and the modem will be unreachable when it's in PSM.

can't capture ppp packets using winpcap sometimes

I am using winpcap on my Windows XP, wishing to capture ppp packets with my WCDMA card.
I have installed winpcap 4.1.3 and Microsoft Network Monitor 3.4.
I compile the example code basic_dump from the winpcap developer's pack. It can always list the ppp card:
1. \Device\NPF_GenericDialupAdapter (Adapter for generic dialup and VPN capture)
2. \Device\NPF_{04F9E6B9-214E-4FE5-892B-0419694392E1} (WAN (PPP/SLIP) Interface)
Sometimes it captures packets and prints timestamp and length as expected, sometimes it just prints nothing even when I am surfing the Internet.
Below is the code.
#ifdef _MSC_VER
/*
* we do not want the warnings about the old deprecated and unsecure CRT functions
* since these examples can be compiled under *nix as well
*/
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "pcap.h"
/* prototype of the packet handler */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
int main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
/* Retrieve the device list */
if(pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
/* Print the list */
for(d=alldevs; d; d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
}
if(i==0)
{
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return -1;
}
printf("Enter the interface number (1-%d):",i);
scanf("%d", &inum);
if(inum < 1 || inum > i)
{
printf("\nInterface number out of range.\n");
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
/* Jump to the selected adapter */
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
/* Open the device */
/* Open the adapter */
if ((adhandle= pcap_open_live(d->name, // name of the device
65536, // portion of the packet to capture.
// 65536 grants that the whole packet will be captured on all the MACs.
0, // promiscuous mode (nonzero means promiscuous)
1000, // read timeout
errbuf // error buffer
)) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
printf("\nlistening on %s...\n", d->description);
/* At this point, we don't need any more the device list. Free it */
pcap_freealldevs(alldevs);
/* start the capture */
pcap_loop(adhandle, 0, packet_handler, NULL);
pcap_close(adhandle);
return 0;
}
/* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
struct tm *ltime;
char timestr[16];
time_t local_tv_sec;
/*
* unused parameters
*/
(VOID)(param);
(VOID)(pkt_data);
/* convert the timestamp to readable format */
local_tv_sec = header->ts.tv_sec;
ltime=localtime(&local_tv_sec);
strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
}

winsock - Sender UDP socket not bound to the desired port

Below you can see my code that implements a pretty basic UDP sender in C++ with Winsock. The thing is that no matter how many times I run the code, the socket (the listenSocket) gets bound to a different UDP port. Is there any specific reason for this? Am I doing some mistake in my code?
thanks
#include <cstdlib>
#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
using namespace std;
int main(int argc, char *argv[])
{
WSADATA wsaData;
SOCKADDR_IN myAddress;
SOCKADDR_IN targetAddress;
int myPort = 60888;
const char *myIP = "192.168.0.1";
int remotePort = 2048;
const char *remoteIP = "192.168.0.2";
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET SendSocket = INVALID_SOCKET;
SOCKET acceptSocket;
char cBuffer[1024] = "Test Buffer";
int nBytesSent = 0;
int nBufSize = strlen(cBuffer);
int iResult;
// Initialize Winsock
if( WSAStartup( MAKEWORD(2, 2), &wsaData ) != NO_ERROR )
{
cerr<<"Socket Initialization: Error with WSAStartup\n";
system("pause");
WSACleanup();
exit(10);
}
ListenSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (ListenSocket == INVALID_SOCKET or SendSocket == INVALID_SOCKET)
{
cerr<<"Socket Initialization: Error creating socket"<<endl;
system("pause");
WSACleanup();
exit(11);
}
//bind
myAddress.sin_family = AF_INET;
myAddress.sin_addr.s_addr = inet_addr(myIP);
myAddress.sin_port = htons(myPort);
targetAddress.sin_family = AF_INET;
targetAddress.sin_addr.s_addr = inet_addr(remoteIP);
targetAddress.sin_port = htons(remotePort);
if(bind(ListenSocket, (SOCKADDR*) &myAddress, sizeof(myAddress)) == SOCKET_ERROR)
{
cerr<<"ServerSocket: Failed to connect\n";
system("pause");
WSACleanup();
exit(14);
}
else
printf("Server: bind() is OK.\n");
nBytesSent = sendto(SendSocket, cBuffer, nBufSize, 0,
(SOCKADDR *) &targetAddress,
sizeof(SOCKADDR_IN));
printf("Everything is ok\n");
system("PAUSE");
closesocket(ListenSocket);
closesocket(SendSocket);
return EXIT_SUCCESS;
}
EDIT: Maybe I was not so clear. What I do with this code is to send some data to a remote PC. But what is required is that the UDP segments should appear to be originated from a specific port. How can this be done? Is it wrong what I'm doing here? Now that I'm thinking of it, I guess it is wrong indeed. The SendSocket and ListenSocket don't have any connection, correct? So, how can I make it that the UDP segments appear to originate from a specific UDP port? Thanks!
You are not calling bind() on SendSocket before sending data with it, so WinSock is free to bind that socket to whatever random local IP/Port it needs to. If you have to send data with a specific source IP/Port every time, you have to bind() to that IP/Port first. If that local IP/Port is the same pair you are binding ListenSocket to, then you don't need to use two separate sockets to begin with. You can send data with the same socket that is listening for incoming data.