#minGW を使った、UDPの送受信関数
windows 7 のDOS窓で動作する関数です。
###送信側
udpsend.c
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <winsock2.h>
int main(int argc, char** argv)
{
int sd;
struct sockaddr_in addr;
WSADATA wsaData;
// winsock2の初期化
WSAStartup(MAKEWORD(2,0), &wsaData);
//socketシステムコール
//ディスクリプタsdを取得する
//SOCK_DGRAM <- UDP, SOCK_STREAM<- TCP
if((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket");
printf("error:%d\n",WSAGetLastError());
return -1;
}
// 送信先アドレスとポート番号を設定する
memset(&addr,0,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(12345); // ポート番号(htons)でネットワークバイトオーダーに変換
addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //IPアドレスを格納したin_addr構造体
// パケットをUDPで送信
if(sendto(sd, "I am send process", 17, 0, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("sendto");
printf("error:%d\n",WSAGetLastError());
return -1;
}
printf("send end\n");
// 接続を切断する
closesocket(sd);
WSACleanup();
return 0;
}
送信側コンパイル
gcc udpsend.c libws2_32.lib
送信側で、送信元のポート番号が欲しい場合、以下を追加
udpsend.c
//送信元のポート番号が欲しい場合
struct sockaddr_in sin;
int addrlen = sizeof(sin);
if(getsockname(sd, (struct sockaddr *)&sin, &addrlen) == 0 &&
sin.sin_family == AF_INET && addrlen == sizeof(sin))
{
int local_port = ntohs(sin.sin_port);
printf("send port %s:%d\n",inet_ntoa(sin.sin_addr),local_port);
}
###受信側
udprecv.c
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <winsock.h>
#include <winsock2.h>
int main()
{
WSADATA wsaData;
SOCKET sockfd, new_sockfd;
int writer_len, recv_len, on;
struct sockaddr_in reader_addr, writer_addr;
struct ip_mreq mreq;
char buf[1024];
// winsock2の初期化
WSAStartup(MAKEWORD(1,1), &wsaData);
//socketシステムコール
//ディスクリプタsdを取得する
//SOCK_DGRAM <- UDP, SOCK_STREAM<- TCP
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket");
printf("error:%d\n",WSAGetLastError());
return -1;
}
/* ファイルディスクリプターで参照されるソケットにオプションの設定 */
/* SOL_SOCKET : ソケット API 層 */
/* SO_REUSEADDR : bindが失敗するのを回避 */
on = 1;
if (setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on) ) == SOCKET_ERROR)
{
perror("setsockopt");
printf("error:%d\n",WSAGetLastError());
return -1;
}
// 受信元アドレスとポート番号を設定する
memset((char *)&reader_addr, 0, sizeof(reader_addr));
reader_addr.sin_family = AF_INET;
reader_addr.sin_addr.s_addr = htonl(INADDR_ANY); //IPアドレスを格納したin_addr構造体
reader_addr.sin_port = htons(12345); // ポート番号(htons)でネットワークバイトオーダーに変換
// ソケットに名前(ポート番号 & IPアドレス)を付ける
if (bind(sockfd, (struct sockaddr *)&reader_addr, sizeof(reader_addr)) < 0) {
perror("bind");
printf("error:%d\n",WSAGetLastError());
closesocket(sockfd);
return -1;
}
while(1) {
//パケットをUDPで受信
recv_len=recv(sockfd, buf, 1024, 0);
if(recv_len>0){
printf("%s\n",buf);
break;
}
}
// 接続を切断する
closesocket(sockfd);
WSACleanup();
}
受信側コンパイル
gcc udpread.c libws2_32.lib