12

udp ソケットに頭を悩ませる試みとして、このチュートリアル ページhttp://www.linuxhowtos.org/C_C++/socket.htmのコードを winsock に移植しようとしました (重要な場合は win 8 で実行)。[以下の直リンク]

コードは現在コンパイルおよび実行されていますが、パケットを受信することはありません。両方のプログラムは、recvfrom() で待機してブロックするだけです。私はこの同じ問題を抱え続けています(たとえば、recvfrom()呼び出しを含むこのコードhttps://stackoverflow.com/a/679529/873217の修正版。そして、このコードC ++の問題でDatagram(UDP)winsocketにsendto と recvfrom をループバック アダプターを介して同じソケットに接続し、提案された変更を行います)。単純で根本的な間違いを犯していると思います。しかし、私は自分でそれを見つけることができません。より多くの経験を持つ誰かが私のためにこの問題に光を当ててくれることを願っています. ありがとう。

追加メモ:
サーバー exe を実行してから、同じコンピューターでクライアント exe を実行しています。インターネットに接続されています。また、自分の IP アドレスにも解決されるドメインを使用してみました。両方のプログラムにフルアクセスを許可しましたが、ファイアウォールも無効にしようとしました。

元のクライアントおよびサーバー コードへの直接リンク:
http://www.linuxhowtos.org/data/6/client_udp.c
http://www.linuxhowtos.org/data/6/server_udp.c

私の現在の試み:

どちらも libws2_32.a にリンクされています

クライアントコード:

#include <stdio.h>
#include <winsock2.h>
#include <string.h>

void error(const char *);

int main()
{
    WSAData data;
    WSAStartup( MAKEWORD( 2, 2 ), &data );

    int sock, n;
    int length;
    struct sockaddr_in server, from;
    struct hostent *hp;
    char buffer[256];
    unsigned short serverPort = 27072;
    sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0) error("socket");
    server.sin_family = AF_INET;
    hp = gethostbyname("localhost");//have also tried my url
    if (hp==0) error("Unknown host");
    memmove((char *)hp->h_addr, (char *)&server.sin_addr, hp->h_length);
    server.sin_port = htons(serverPort);
    length = sizeof(struct sockaddr_in);
    printf("Please enter the message: ");
    memset(buffer, 0, 256);
    fgets(buffer, 255, stdin);
    n = sendto (sock, buffer, strlen(buffer), 0, (const struct sockaddr *)&server, length);
    if (n < 0) error("Sendto");
    printf("sent %i bytes\n", n);
    n = recvfrom(sock, buffer, 256, 0, (struct sockaddr *)&server, &length);
    if (n < 0) error("recvfrom");
    //write(1,"Got an ack: ", 12);
    //write(1, buffer, n);
    printf("Got msg: %s\n",buffer);

    closesocket(sock);
    WSACleanup();
    return(0);
}

void error(const char *msg)
{
    perror(msg);
    exit(0);
}

サーバーコード:

#include <stdio.h>
#include <winsock2.h>
#include <string.h>

void error(const char *);

int main()
{
    WSAData data;
    WSAStartup( MAKEWORD( 2, 2 ), &data );

    int sock, length, n;
    int fromlen;
    struct sockaddr_in server;
    struct sockaddr_in from;
    char buf[1024];
    unsigned short serverPort = 27072;
    sock=socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0) error("Opening socket");
    length = sizeof(server);
    memset(&server, 0, length);
    server.sin_family = AF_INET;
    server.sin_addr.s_addr=INADDR_ANY;
    server.sin_port=htons(serverPort);
    if (bind(sock,(struct sockaddr *)&server, length)<0) error ("binding");
    fromlen = sizeof(struct sockaddr_in);
    while(1)
    {
        n = recvfrom(sock, buf, 1024, 0, (struct sockaddr *)&from, &fromlen);
        if (n<0) error("recvfrom");
        //write(1,"Received a datagram: ", 21);
        //write(1,buf,n);
        printf("Received a datagram: %s", buf);
        n = sendto(sock, "Got your message\n",17,0,(struct sockaddr *)&from,fromlen);
        if (n<0)error("sendto");
    }
    closesocket(sock);
    WSACleanup();
    return 0;
}


void error (const char *msg)
{
    perror(msg);
    exit(0);
}
4

2 に答える 2

0

winsock2.h が Windows と Linux で同じように機能するかどうかはわかりませんが、Windows では、ソケットを作成するときに、使用しているプロトコルを TCP または UDP のいずれかに設定する必要があります。

SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

AF_INET = IPv4; SOCK_STREAM = TCP のバイト ストリーム。IPPROTO_TCP = TCP プロトコル。

UDP (これまで使用したことがありません) の場合、MSDN によると、次のようになります。

SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

SOCK_DGRAM = UDP のバイト ストリーム。IPPROTO_UDP = UDP プロトコル。

そのコードは Windows で動作します。Linuxでも同様だと思います。

于 2013-02-03T19:45:06.007 に答える