[kaze's test] プログラミングメモ →目次


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

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

メモとして、下記の3関数を作りました。
udp_receive()は、recvfrom()で受信受信します。受信データが入るまで抜けません。
udp_receive_select()は、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;

}