2017-04-09 23 views
0

UDPソケットからメッセージを受け取るのに問題があります。 私はC++のサーバーとクライアントのアプリケーションをうまく動作させました。サーバーはクライアントからのメッセージを受信し、応答を返信し、クライアントはメッセージを受信して​​、両方ともソケットを閉じて終了します。今、私はC#でクライアントプログラムを作成しようとしていますが、サーバーからメッセージを受け取ることができません。クライアントC#アプリはメッセージを送信した後、C++サーバはそれを正しく受信しますが、サーバが応答を送り返すと、クライアントはそれを受け取ることができません。私はローカル仮想マシン上の私のサーバーをテストして、VPSで結果は同じでした。何か案が?C#UDPソケットがメッセージを受信できません

Serverコードの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; 
} 

クライアントコードの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; 
} 

ここでは動作しません、私の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(); 
     } 
    } 
} 

は、別の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(); 
     } 
    } 
} 
+0

あなたのメッセージを送った後に 'server'ソケットを閉じないでください。サーバーはそのソケットに応答を送信します。ソケットを閉じると返信を受け取ることができません。実際に 'UdpClient'を使ってレスポンスを受け取るには、パラメータのないコンストラクタを使用し、' Client'プロパティを割り当てます: 'UdpClient listener = new UdpClient {Client = server};'。しかし私には、あなたは 'UdpClient'をスキップし、' server.ReceiveFrom() 'を使って返信を受け取るべきだと思います。 –

答えて

0

ありがとうございます@ピーター! ここで私のコードを見直した後、解決策はあります:

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(); 
    } 
    } 
} 
関連する問題