IPパケットサイズ制限を越えてUDPを送受信する
ためにCで簡単な処理のsendto, recvfrom, sendラッパー関数を作成。
まだまだパフォーマンス確認のためのテスト実装なので、再送やエラー処理はなし。
ここで凝ってしまうとTCPになってしまうのであえてシンプルに。
実用上有益というよりは、たったこれだけで越えられるんだよ!というメモ。
#include <stdio.h> #include <stdlib.h> #include <winsock.h> #include <pthread.h> #include <strings.h> #include <sys/types.h> #include <sys/stat.h> #include "userlog.h" #include "mudp.h" #define IP_MAX_SIZE 65000 #define MAX_BMP_SIZE 1920*1080*3 int mudp_sendto(SOCKET sock, char *buf, int len, int flags, struct sockaddr *to, int tolen) { char *mudpBuf; char packetNum; int mudpLen; packetNum = ((len % IP_MAX_SIZE) == 0 ) ? (len / IP_MAX_SIZE) : (len / IP_MAX_SIZE)+1; mudpBuf = (char*)malloc(IP_MAX_SIZE+1); for(int i=0;i<packetNum;i++){ *mudpBuf = i; if (len<(i+1)*IP_MAX_SIZE) { memcpy(mudpBuf+1, buf+(IP_MAX_SIZE*i), len % IP_MAX_SIZE); mudpLen = (len % IP_MAX_SIZE)+1; } else { memcpy(mudpBuf+1, buf+(IP_MAX_SIZE*i), IP_MAX_SIZE); mudpLen = IP_MAX_SIZE + 1; } int ret = sendto(sock, mudpBuf, mudpLen, flags, to, tolen); if(ret==SOCKET_ERROR) { LOG_ERROR("mUDP send socket error:%d seqno:%d.\n", WSAGetLastError(), i); } } free(mudpBuf); return 0; } int mudp_recvfrom(SOCKET sock, char *buf, int len, int flags, struct sockaddr *to, int *tolen) { char *tmpBuf; tmpBuf = (char*)malloc(IP_MAX_SIZE+1); int retSize=0; for(int i=0;;i++) { int ret = recvfrom(sock, (char *)tmpBuf, IP_MAX_SIZE+1, 0, to, tolen); if ( ret == SOCKET_ERROR ) { LOG_ERROR("mUDP recv socket error %d seqno:%d.\n", WSAGetLastError(), i); return SOCKET_ERROR; } else if (*tmpBuf != i) { return DROPPED; } else { memcpy(buf+(IP_MAX_SIZE*i), tmpBuf+1, ret-1); retSize += ret-1; if (ret < IP_MAX_SIZE) break; } } return retSize; } int mudp_recv(SOCKET sock, char *buf, int len, int flags) { int retSize = mudp_recvfrom(sock, buf, len, flags, NULL, NULL); return retSize; }