简体   繁体   English

C#UDP套接字无法接收消息

[英]C# UDP socket unable to receive message

I'm having problema to receive message from UDP socket. 我在从UDP套接字接收消息时遇到问题。 I have made C++ server and client aplications that works fine. 我已经使C ++服务器和客户端应用程序正常工作。 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. 现在,我尝试使用C#创建客户端程序,但无法从服务器接收消息。 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. 客户端C#应用发送该消息,然后C ++ Server正确接收该消息,但是当服务器发回其响应时,客户端将无法接收该消息。 I have tested my server on local virtual machine and on VPS the result was the same. 我已经在本地虚拟机和VPS上测试了服务器,结果是相同的。 Any idea? 任何想法?

Server code C++: 服务器代码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++: 客户端代码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: 这是我的C#代码不起作用:

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: 这是另一个无效的C#代码:

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();
        }
    }
}

Thank you @Peter! 谢谢@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();
    }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM