プログラミングメモ →目次


UDPソケット送受信(VC++)

Windows Sockets APIを使用するUDPソケット送受信のメモです。

メモとして、下記の3関数を作りました。テスト時に、別々の実行ファイルを作ります。
udp_receive()は、select()を使用して受信できるまで待ちます。
udp_receive_select()は、一定の時間まで受信を待ちます。
udp_send()は、送信します。

注:メモとして送信用のソケットと受信用のソケットを作っていましたが、一つのソケットで、送信と受信できます。

#include "stdafx.h"
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")

//受信テスト
void udp_receive() 
{
unsigned short port = 10000;
    SOCKET sockRecv;
    struct sockaddr_in sockAddrIn;

    memset(&sockAddrIn, 0, sizeof(sockAddrIn));
    sockAddrIn.sin_port = htons(port);
    sockAddrIn.sin_family = AF_INET;
    sockAddrIn.sin_addr.s_addr = htonl(INADDR_ANY);

    sockRecv = socket(AF_INET, SOCK_DGRAM, 0);
    if (INVALID_SOCKET == sockRecv)
        return;
 
    if (SOCKET_ERROR == bind(sockRecv, (const struct sockaddr *) &sockAddrIn, sizeof(sockAddrIn)))
    {
        closesocket(sockRecv);
        return;
    }

    char buff[256];
    memset(buff, 0, sizeof(buff));
    int ilen = recvfrom(sockRecv, buff, 256, 0, NULL, NULL);
    if (ilen > 0)
    {
        printf("Data Received = %s\r\n", buff);
    }
    closesocket(sockRecv);
}

//送信テスト
void udp_send()
{
    unsigned short port = 10000;
    SOCKET sockSend;
    struct sockaddr_in sockAddrIn;

    memset(&sockAddrIn, 0, sizeof(sockAddrIn));
    sockAddrIn.sin_addr.s_addr = inet_addr("192.168.0.5");
    sockAddrIn.sin_port = htons(port);
    sockAddrIn.sin_family = AF_INET;

    sockSend = socket(AF_INET, SOCK_DGRAM, 0);
    if (INVALID_SOCKET == sockSend)
        return;
        
    char buff[] = "udp test sending ..."; 
    sendto(sockSend, buff, strlen(buff)+1, 0, (const struct sockaddr *)&sockAddrIn, sizeof(sockAddrIn));

    closesocket(sockSend);
}

//受信テスト(select使用)
void udp_receive_select() 
{
    unsigned short port = 10000;
    SOCKET sockRecv;
    struct sockaddr_in sockAddrIn;

    memset(&sockAddrIn, 0, sizeof(sockAddrIn));
    sockAddrIn.sin_port = htons(port);
    sockAddrIn.sin_family = AF_INET;
    sockAddrIn.sin_addr.s_addr = htonl(INADDR_ANY);

    sockRecv = socket(AF_INET, SOCK_DGRAM, 0);
    if (INVALID_SOCKET == sockRecv)
        return;
 
    if (SOCKET_ERROR == bind(sockRecv, (const struct sockaddr *) &sockAddrIn, sizeof(sockAddrIn)))
    {
        closesocket(sockRecv);
        return;
    }

    while (1)
    {
        fd_set mask;
        FD_ZERO(&mask);
        FD_SET(sockRecv, &mask);
        struct timeval tv={ 1, 0 };

        int ret = select((int)sockRecv+1, &mask, NULL, NULL, &tv);
        if (ret == SOCKET_ERROR)
            return;
        else if (ret == 0)
        {
            printf("wait 1 second ...\r\n");
            continue;
        }
        else if (FD_ISSET(sockRecv, &mask))
        {
            break;
        }
    }

    char buff[256];
    memset(buff, 0, sizeof(buff));
    int ilen = recvfrom(sockRecv, buff, 256, 0, NULL, NULL);
    if (ilen > 0)
    {
        printf("Data Received = %s\r\n", buff);
    }
    closesocket(sockRecv);
}

int main(int argc, char* argv[])
{
    WSADATA wsadata;
    if (0 != WSAStartup(MAKEWORD(2,0), &wsadata))
    {
        printf("WSAStartup Faild.\n");
        return -1;
    }

    //udp_receive();
    //udp_receive_select();
    //udp_send();

    WSACleanup();
    return 0;

}