Last active
August 29, 2015 14:17
-
-
Save sgk/effc684bee85bbd7b133 to your computer and use it in GitHub Desktop.
受信したNICアドレスから返すUDPエコーサーバ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*.swp | |
a.out | |
*.o | |
*.pyc |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
#include <net/if.h> | |
#include <string.h> // memcpy | |
#include <iostream> | |
#include <stdio.h> | |
#include <stdlib.h> | |
int main() { | |
int sock; | |
sock = socket(AF_INET, SOCK_DGRAM, 0); | |
if (sock < 0) { | |
perror("socket"); | |
exit(1); | |
} | |
int one = 1; | |
if (setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &one, sizeof (one)) < 0) { | |
perror("setsockopt(IP_PKTINFO)"); | |
exit(1); | |
} | |
sockaddr_in sin; | |
sin.sin_family = AF_INET; | |
sin.sin_addr.s_addr = htonl(INADDR_ANY); | |
sin.sin_port = htons(3000); | |
if (bind(sock, (sockaddr*)&sin, sizeof (sin)) < 0) { | |
perror("bind"); | |
exit(1); | |
} | |
for (;;) { | |
char buf[4096]; // 受信データ | |
iovec iov[1]; | |
iov[0].iov_base = buf; | |
iov[0].iov_len = sizeof (buf); | |
char cbuf[1024]; // 制御データ | |
msghdr msg; | |
msg.msg_name = &sin; // 送信元アドレスが返る | |
msg.msg_namelen = sizeof (sin); | |
msg.msg_iov = iov; // 受信データが返る | |
msg.msg_iovlen = sizeof (iov) / sizeof (iovec); | |
msg.msg_control = cbuf; // 制御データが返る | |
msg.msg_controllen = sizeof (cbuf); | |
// 受信 | |
int length = recvmsg(sock, &msg, 0); | |
if (length < 0) { | |
perror("recvmsg"); | |
continue; | |
} | |
// 解釈 | |
in_addr localaddr; | |
cmsghdr* cm; | |
for (cm = CMSG_FIRSTHDR(&msg); cm != 0; cm = CMSG_NXTHDR(&msg, cm)) { | |
if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_PKTINFO) { | |
localaddr = ((in_pktinfo*)CMSG_DATA(cm))->ipi_spec_dst; | |
break; | |
} | |
} | |
if (cm == 0) { | |
std::cerr << "IP_PKTINFO not found" << std::endl; | |
continue; | |
} | |
// 応答を構築 | |
iov[0].iov_len = length; | |
msg.msg_name = &sin; // 宛先 | |
msg.msg_namelen = sizeof (sin); | |
msg.msg_iov = iov; // 送信データ | |
msg.msg_iovlen = sizeof (iov) / sizeof (iovec); | |
msg.msg_control = cbuf; // 制御データをこのあと構築 | |
msg.msg_controllen = sizeof (cbuf); | |
// 制御データを構築 | |
in_pktinfo pktinfo; | |
pktinfo.ipi_ifindex = 0; | |
pktinfo.ipi_spec_dst = localaddr; | |
pktinfo.ipi_addr.s_addr = INADDR_ANY; | |
cm = CMSG_FIRSTHDR(&msg); | |
cm->cmsg_level = IPPROTO_IP; | |
cm->cmsg_type = IP_PKTINFO; | |
cm->cmsg_len = CMSG_LEN(sizeof (pktinfo)); | |
memcpy(CMSG_DATA(cm), &pktinfo, sizeof (pktinfo)); | |
msg.msg_controllen = cm->cmsg_len; | |
// 応答 | |
if (sendmsg(sock, &msg, 0) < 0) { | |
perror("sendmsg"); | |
continue; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import socket | |
import sys | |
# command message dst | |
message = 'test message' | |
dst = '127.0.0.1' | |
if len(sys.argv) > 1: | |
message = sys.argv[1] | |
if len(sys.argv) > 2: | |
dst = sys.argv[2] | |
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | |
sock.sendto(message, (dst, 3000)) | |
(message, source) = sock.recvfrom(1024) | |
print "%s: '%s'" % (source, message) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment