サーバとのI/FとしてUDPにて通信を行えるようにしておきます。
これは、現在XPORTとPICマイコンでサーバ(ALIX。3D3)と通信しているもの等を
Raspberry PiとPICマイコンに置き換える準備です。
(TCPでなくUDPの理由は、マイコン制御とI/Fにおいて使い勝手が良い為)
サーバ側送受信の基本形
コンパイルと実行テスト
サーバ側
root@ALIX:/home/xyz/gcc:/# gcc -o us001 us001.c root@ALIX:/home/xyz/gcc:/# ./us001 |
クライアント側
root@pi-170:/home/xyz/gcc:/# gcc -o uc001 uc001.c root@pi-170:/home/xyz/gcc:/# ./uc001 |
ソースファイル:us001.c
// // linux UDPによるLAN接続(サーバ側:基本型) // // recv timeout 10sec // // v001. 2012.9.7 // #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h> // memset対応 #define PORT1 12345 #define PORT2 12346 #define C1 "192.168.0.170" #define C2 "192.168.0.171" int sock1,sock2; struct sockaddr_in s1_addr , s2_adds; struct sockaddr_in cc_addr; char r1_buf[2048]; char r2_buf[2048]; char s_buf[2048]; char senderstr[16]; struct sockaddr_in senderinfo; socklen_t addrlen; // ------------------------------------------------------------ // ------------------------------------------------------------ int udp_recv(){ fd_set fds, readfds; struct timeval tv; int maxfd; int n,ret; while(1){ // ------------------------------------------------------------ // 受信ソケット1 // 受信ソケット2 // ----------------------------- sock1 = socket(AF_INET, SOCK_DGRAM, 0); // sock2 = socket(AF_INET, SOCK_DGRAM, 0); if(sock1 < 0){ printf("socker Error\n"); return(-1); } // if(sock2 < 0){ // printf("socker Error\n"); // return(-1); // } s1_addr.sin_family = AF_INET; // s2_addr.sin_family = AF_INET; s1_addr.sin_port = htons(PORT1); // s2_addr.sin_port = htons(PORT2); s1_addr.sin_addr.s_addr = INADDR_ANY; // s2_addr.sin_addr.s_addr = INADDR_ANY; ret = bind(sock1, (struct sockaddr *)&s1_addr, sizeof(s1_addr)); // ret = bind(sock2, (struct sockaddr *)&s2_addr, sizeof(s2_addr)); // ----------------------------- FD_ZERO(&readfds); //fd_setの初期化 FD_SET(sock1, &readfds); // selectで待つ読込みソケットとしてsock1を登録 tv.tv_sec = 10; //10秒でタイムアウトするように tv.tv_usec = 0; // if(sock1 > sock2){maxfd = sock1;} // else{maxfd = sock2;} maxfd = sock1; // ファイルディスクリプタの最大値 /* 読み込み用fd_setを毎回初期化する */ memcpy(&fds, &readfds, sizeof(fd_set)); /* 設定されたソケットが読込み可能になるまで待つ */ // ----------------------------- n = select(maxfd+1, &fds, NULL, NULL, &tv); // -------------------------------------------------------------------------------------- // maxfd+1 : ファイルディスクリプタの最大値に 1 を足したもの // &fds : recvやrecvfromによる受信を監視するファイルディスクリプタのfd_set型をポインタ指定 // -------------------------------------------------------------------------------------- if (n == 0){ // タイムアウトの場合にselectは0を返す printf("[udp_recv]timeout\n"); break; } // ----------------------------- if (FD_ISSET(sock1, &fds)) { // sock1に読み込み可能データがある場合 memset(r1_buf, 0, sizeof(r1_buf)); /* recvfrom()にてUDPソケットからデータを受信する */ addrlen = sizeof(senderinfo); n = recvfrom(sock1, r1_buf, sizeof(r1_buf) - 1, 0, (struct sockaddr *)&senderinfo, &addrlen); /* 送信元に関する情報を表示 */ inet_ntop(AF_INET, &senderinfo.sin_addr, senderstr, sizeof(senderstr)); printf("[udp_recv]ip=[%s]port=[%d]\n", senderstr, ntohs(senderinfo.sin_port)); /* 受信データの表示 */ printf("[udp_recv1]%s\n", r1_buf); } // ----------------------------- // if (FD_ISSET(sock2, &fds)) { // sock2に読み込み可能データがある場合 // memset(r2_buf, 0, sizeof(r2_buf)); /* recvfrom()にてUDPソケットからデータを受信する */ // addrlen = sizeof(senderinfo); // n = recvfrom(sock2, r2_buf, sizeof(r2_buf) - 1, 0, // (struct sockaddr *)&senderinfo, &addrlen); /* 送信元に関する情報を表示 */ // inet_ntop(AF_INET, &senderinfo.sin_addr, senderstr, sizeof(senderstr)); // printf("[udp_recv2]ip=[%s]port=[%d]\n", senderstr, ntohs(senderinfo.sin_port)); /* 受信データの表示 */ // printf("[udp_recv]%s\n", r2_buf); // ----------------------------- // } } // ----------------------------- close(sock1); // close(sock2); printf("[udp_recv] fin\n"); return(0); } // ------------------------------------------------------------ // ------------------------------------------------------------ int udp_send(int port_no , char ip_adds[]){ sock1 = socket(AF_INET, SOCK_DGRAM, 0); if(sock1 < 0){ printf("socker Error\n"); return(-1); } cc_addr.sin_family = AF_INET; cc_addr.sin_port = htons(port_no); cc_addr.sin_addr.s_addr = inet_addr(ip_adds); sendto(sock1, s_buf, strlen(s_buf), 0, (struct sockaddr *)&cc_addr, sizeof(cc_addr)); close(sock1); return(0); } // ------------------------------------------------------------ // ------------------------------------------------------------ int main(){ int ret; int port_no; char ip_adds[20]; ret = udp_recv(); // data-recv if(ret < 0){return -1;} strcpy(s_buf,r1_buf); port_no = PORT1; strcpy( ip_adds , C1); ret = udp_send(port_no , ip_adds); // data-send if(ret < 0){return -1;} return 0; } |
ソースファイル:uc001.c
// // linux UDPによるLAN接続(クライアント側:基本型) // (Rasspberry Pi) // recv timeout 10sec // // v001. 2012.9.7 // #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h> // memset対応 #define PORT 12345 // #define Send_IPadds "127.0.0.1" #define Send_IPadds "192.168.0.100" #define My_IPadds "192.168.0.170" int sock1 ; struct sockaddr_in ss_addr; struct sockaddr_in cc_addr; char s_buf[2048]; char r1_buf[2048]; char senderstr[16]; struct sockaddr_in senderinfo; socklen_t addrlen; // --------------------------------------------------------- // --------------------------------------------------------- int udp_send(){ printf("send-data = "); // コンソールデータ入力 scanf("%s",s_buf); // コンソールデータ入力 sock1 = socket(AF_INET, SOCK_DGRAM, 0); if(sock1 < 0){ printf("socker Error\n"); return(-1); } ss_addr.sin_family = AF_INET; ss_addr.sin_port = htons(PORT); ss_addr.sin_addr.s_addr = inet_addr(Send_IPadds); // sendto(sock1 , "HELLO", 5, 0, (struct sockaddr *)&ss_addr, sizeof(ss_addr)); // sendto(sock1 , My_IPadds, sizeof(My_IPadds), 0, (struct sockaddr *)&ss_addr, sizeof(ss_addr)); sendto(sock1 , s_buf, sizeof(s_buf), 0, (struct sockaddr *)&ss_addr, sizeof(ss_addr)); close(sock1 ); printf("send end !\n"); } // --------------------------------------------------------- // --------------------------------------------------------- int udp_recv(){ fd_set fds, readfds; int maxfd; int n,ret; struct timeval tv; while(1){ sock1 = socket(AF_INET, SOCK_DGRAM, 0); if(sock1 < 0){ printf("socker Error\n"); return(-1); } cc_addr.sin_family = AF_INET; cc_addr.sin_port = htons(PORT); cc_addr.sin_addr.s_addr = inet_addr(My_IPadds); ret = bind(sock1, (struct sockaddr *)&cc_addr, sizeof(cc_addr)); FD_ZERO(&readfds); //fd_setの初期化 FD_SET(sock1, &readfds); // selectで待つ読込みソケットとしてsock1を登録 tv.tv_sec = 10; //10秒でタイムアウトするように tv.tv_usec = 0; /* 読み込み用fd_setの初期化 */ /* selectが毎回内容を上書きしてしまうので、毎回初期化する */ memcpy(&fds, &readfds, sizeof(fd_set)); /* fdsに設定されたソケットが読込み可能になるまで待つ */ n = select(sock1+1, &fds, NULL, NULL, &tv); if (n == 0){ // タイムアウトの場合にselectは0を返す printf("[udp_recv]timeout\n"); break; } /* sock1に読み込み可能データがある場合 */ if (FD_ISSET(sock1, &fds)){ // sock1に読み込み可能データがある場合 memset(r1_buf, 0, sizeof(r1_buf)); /* recvfrom()を利用してUDPソケットからデータを受信 */ addrlen = sizeof(senderinfo); n = recvfrom(sock1, r1_buf, sizeof(r1_buf) - 1, 0, (struct sockaddr *)&senderinfo, &addrlen); /* 送信元に関する情報を表示 */ inet_ntop(AF_INET, &senderinfo.sin_addr, senderstr, sizeof(senderstr)); printf("[udp_recv]ip=[%s]port=[%d]\n", senderstr, ntohs(senderinfo.sin_port)); printf("[udp_recv]%s\n", r1_buf); break; } } close(sock1 ); return 0; } // --------------------------------------------------------- // --------------------------------------------------------- int main(){ int ret; ret = udp_send(); if(ret < 0){return -1;} ret = udp_recv(); if(ret < 0){return -1;} return 0; } |