Kiril Tsvetanov Kiril Tsvetanov - 1 month ago 15
C# Question

C# UDP socket unable to receive message

I'm having problema to receive message from UDP socket.
I have made C++ server and client aplications that works fine. The server receive message from client then send back response, the client receive the message and then both of them close the sockets and exit. Now I'm try to create the client program with C# I'm unable to receive the message from the server. The client C# app send the message then C++ Server recieve it correctly but when the server sent back his response the client is unable to receive it. I have tested my server on local virtual machine and on VPS the result was the same. Any idea?

Server code C++:

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <pthread.h>

#define MSG "Hi i'm server"
#define SERVERPORT "8642"
#define MAXBUFLEN 100


// Get sockaddr, IPv4 or IPv6.
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET)
{
return &(((struct sockaddr_in*)sa)->sin_addr);
}

return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int LoginUser()
{
int locUserId = 0;

// Call DB.

return 0;
}

int main(int argc, char *argv[])
{
// Load up address structs.
struct addrinfo hints, *res;

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // Use IPv4 or IPv6, whichever.
hints.ai_socktype = SOCK_DGRAM; // UDP.
hints.ai_flags = AI_PASSIVE; // Fill in my IP for me.

int locInitAddrInfo = getaddrinfo(NULL, SERVERPORT, &hints, &res);

if (locInitAddrInfo != 0)
{
printf("Error initialize address info: %s\n", gai_strerror(locInitAddrInfo));
return 1;
}

printf("Address info initialized: %i\n", locInitAddrInfo);

// Initialize the socket.
int locInitSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);

if (locInitSocket == -1)
{
printf("Error initialize socket: %s\n", strerror(errno));
freeaddrinfo(res);
return 2;
}

printf("Socket initialized: %i\n", locInitSocket);

// Bind a name to a socket.
int locInitBind = bind(locInitSocket, res->ai_addr, res->ai_addrlen);

if (locInitBind == -1)
{
printf("Error bind socket: %s\n", strerror(errno));
freeaddrinfo(res);
close(locInitSocket);
return 3;
}

printf("Socket binded: %i\n", locInitBind);

// Receive message from client.
char buf[MAXBUFLEN];
struct sockaddr_storage their_addr;
socklen_t addr_len = sizeof their_addr;

int locNumByteRecv = recvfrom(locInitSocket, buf, MAXBUFLEN, 0, (struct sockaddr *)&their_addr, &addr_len);

if (locNumByteRecv == -1)
{
printf("Error receive from: %s\n", strerror(errno));
freeaddrinfo(res);
close(locInitSocket);
return 4;
}

// -----------------------------------------
char s[INET6_ADDRSTRLEN];

printf("Server: got packet from %s\n", inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s));
printf("Server: packet is %d bytes long\n", locNumByteRecv);
buf[locNumByteRecv] = '\0';
printf("Server: packet contains \"%s\"\n", buf);
// -----------------------------------------

sleep(2);

// Send to client.
int locNumByteSend = sendto(locInitSocket, MSG, strlen(MSG), 0, (struct sockaddr *)&their_addr, addr_len);

if (locNumByteSend == -1)
{
printf("Error send to: %s\n", strerror(errno));
freeaddrinfo(res);
close(locInitSocket);
return 5;
}

printf("Server: sent %d bytes to %s:%s\n", locNumByteSend, inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s), SERVERPORT);

// Free the linked-list.
freeaddrinfo(res);

// Close the socket.
close(locInitSocket);

printf("Socket closed.\nHave a nice day :)\n");

return 0;
}


Client code C++:

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>

#define MSG "Hi i'm client"
#define SERVERIP "192.168.1.33"
#define SERVERPORT "8642"
#define MAXBUFLEN 100

// Get sockaddr, IPv4 or IPv6.
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET)
{
return &(((struct sockaddr_in*)sa)->sin_addr);
}

return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int main(int argc, char *argv[])
{
// Load up address structs.
struct addrinfo hints, *res;

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // Use IPv4 or IPv6, whichever.
hints.ai_socktype = SOCK_DGRAM; // UDP.

int locInitAddrInfo = getaddrinfo(SERVERIP, SERVERPORT, &hints, &res);

if (locInitAddrInfo != 0)
{
printf("Error initialize address info: %s\n", gai_strerror(locInitAddrInfo));
return 1;
}

printf("Address info initialized: %i\n", locInitAddrInfo);

// Initialize the socket.
int locInitSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);

if (locInitSocket == -1)
{
printf("Error initialize socket: %s\n", strerror(errno));
freeaddrinfo(res);
return 2;
}

printf("Socket initialized: %i\n", locInitSocket);

// Send to server.
int locNumByteSend = sendto(locInitSocket, MSG, strlen(MSG), 0, res->ai_addr, res->ai_addrlen);

if (locNumByteSend == -1)
{
printf("Error send to: %s\n", strerror(errno));
freeaddrinfo(res);
close(locInitSocket);
return 3;
}

printf("Client: sent %d bytes to %s:%s\n", locNumByteSend, SERVERIP, SERVERPORT);

// Receive message from server.
char buf[MAXBUFLEN];
struct sockaddr_storage their_addr;
socklen_t addr_len = sizeof their_addr;

int locNumByteRecv = recvfrom(locInitSocket, buf, MAXBUFLEN, 0, (struct sockaddr *)&their_addr, &addr_len);

if (locNumByteRecv == -1)
{
printf("Error receive from: %s\n", strerror(errno));
freeaddrinfo(res);
close(locInitSocket);
return 4;
}

// -----------------------------------------
char s[INET6_ADDRSTRLEN];

printf("Client: got packet from %s\n", inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s));
printf("Client: packet is %d bytes long\n", locNumByteRecv);
buf[locNumByteRecv] = '\0';
printf("Client: packet contains \"%s\"\n", buf);
// -----------------------------------------

// Free the linked-list.
freeaddrinfo(res);

// Close the socket.
close(locInitSocket);

printf("Socket closed.\nHave a nice day :)\n");

return 0;
}


Here is my C# code that doesn't work:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace TestCSharpSocket
{
class Program
{
static void Main(string[] args)
{
try
{
// This work fine ----------------------------
IPEndPoint RemoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.33"), 8642);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
string welcome = "Welcome";
byte[] data = Encoding.ASCII.GetBytes(welcome);
server.SendTo(data, data.Length, SocketFlags.None, RemoteEndPoint);
server.Close();

Console.WriteLine("Welcome send");

// End This work fine ----------------------------

IPHostEntry hostEntry = Dns.GetHostEntry(Dns.GetHostName());
IPEndPoint ServerEndPoint = new IPEndPoint(IPAddress.Any, 8642);
Socket WinSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
WinSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000);


IPEndPoint sender = new IPEndPoint(IPAddress.Any, 8642);
EndPoint Remote = (EndPoint)(sender);

WinSocket.Bind(ServerEndPoint);

data = new byte[256];
int recv = WinSocket.ReceiveFrom(data, ref Remote);
WinSocket.Close();


Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
}
catch (SocketException sex)
{
Console.WriteLine("Time Out: " + sex.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}

Console.ReadLine();
}
}
}


Here is another C# code that doesn't work:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace TestCSharpSocket
{
class Program
{
static void Main(string[] args)
{
try
{
// This work fine ----------------------------
IPEndPoint RemoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.33"), 8642);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
string welcome = "Welcome";
byte[] data = Encoding.ASCII.GetBytes(welcome);
server.SendTo(data, data.Length, SocketFlags.None, RemoteEndPoint);
server.Close();

Console.WriteLine("Welcome send");

// End This work fine ----------------------------

UdpClient listener = new UdpClient(8642);
listener.Client.ReceiveTimeout = 5000;
IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 8642);

byte[] receivebytes;
receivebytes = listener.Receive(ref endpoint);

Console.WriteLine(Encoding.ASCII.GetString(receivebytes, 0, receivebytes.Length));
}
catch (SocketException sex)
{
Console.WriteLine("Time Out: " + sex.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}

Console.ReadLine();
}
}
}

Answer

Thank you @Peter! After I review my code here is the solution:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace TestCSharpSocket
{
  class Program
  {
    static void Main(string[] args)
    {
        try
        {
            // This work fine  ----------------------------
            IPEndPoint RemoteEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.33"), 8642);
            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            string welcome = "Welcome";
            byte[] data = Encoding.ASCII.GetBytes(welcome);
            server.SendTo(data, data.Length, SocketFlags.None, RemoteEndPoint);

            Console.WriteLine("Welcome send");

            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
            EndPoint Remote = (EndPoint)(sender);

            data = new byte[256];
            int recv = server.ReceiveFrom(data, ref Remote);
            server.Close();

            Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
        }
        catch (SocketException sex)
        {
            Console.WriteLine("Time Out: " + sex.ToString());
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }

        Console.ReadLine();
    }
  }
}