ソケット通信が思うように出来ない
Q&A
『Tera Term』を使用し、『Raspberry Pi』でのソケット通信を試みました。しかし、実行まではうまくいかず、通信は失敗したようでした。
※ソケット名は次のようにしています。
対象 | 変数名 |
---|---|
ソケット(サーバ) | sock_s |
ソケット(クライアント) | sock_c |
接続済のソケット(サーバ) | c_sock_s |
サーバ
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define SERVER_PORT 8080
#define BUF_SIZE 1024
void transfer(int tf_sock){
char send_buf[100], recv_buf[100];
int send_size, recv_size;
while (1) {
recv_size = recv(tf_sock, recv_buf, sizeof(recv_buf), 0);
if (recv_size == 1) {
printf("recv error\n");
exit(1);
}
if (recv_size == 0) {
/* 受信サイズが0の場合は相手が接続閉じていると判断 */
printf("connection ended\n");
continue;
}
printf("%s\n", recv_buf);
}
}
int main(){
int sock_s = socket(AF_INET, SOCK_STREAM, 0); //ソケットを作成
if (sock_s == 1) {
printf("ソケットエラーです\n");
return 1;
}
//IPアドレスやポート番号の指定
struct sockaddr_in sv_addr;
memset(&sv_addr, 0, sizeof(struct sockaddr_in));
sv_addr.sin_family = AF_INET;
sv_addr.sin_port = htons((unsigned short)SERVER_PORT);
sv_addr.sin_addr.s_addr = INADDR_ANY;
if ( bind(sock_s, (struct sockaddr *)&sv_addr, sizeof(sv_addr)) == 1 ) { //ソケット登録
printf("bind error\n");
close(sock_s);
return 1;
}
while (1) {
if ( listen(sock_s, SOMAXCONN) == 1 ) { //接続待ち
printf("listen error\n");
close(sock_s);
return 1;
}
printf("Waiting connect...\n");
struct sockaddr_in get_addr;
socklen_t len = sizeof(struct sockaddr_in);
int c_sock_s = accept(sock_s, (struct sockaddr *)&get_addr, &len); //接続要求の受け付け
if (c_sock_s == 1) {
printf("accept error\n");
close(sock_s);
return 1;
}
printf("Connected successfully.\n");
transfer(c_sock_s); //通信
close(c_sock_s);
}
//クローズ
close(sock_s);
}
クライアント
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define SERVER_PORT 8080
#define BUF_SIZE 1024
void transfer(int tf_sock){
char send_buf[100], recv_buf[100];
int send_size, recv_size;
while(1){
printf("Input Message here : ");
scanf("%s", send_buf); //サーバーへ送信する文字列を キーボードより読み込む
send_size = send(tf_sock, send_buf, sizeof(send_buf), 0); //送信
if (send_size == 1) {
printf("send error\n");
exit(1);
}
recv_size = recv(tf_sock, &recv_buf, sizeof(recv_buf), 0); //サーバからの応答を受信
if (recv_size == 1) {
printf("recv error\n");
exit(1);
}
}
}
int main(){
int sock_c = socket(AF_INET, SOCK_STREAM, 0); //ソケットを作成
if (sock_c == 1) {
printf("ソケットエラーです\n");
return 1;
}
//IPアドレスやポート番号の指定
struct sockaddr_in ce_addr;
memset(&ce_addr, 0, sizeof(struct sockaddr_in));
ce_addr.sin_family = AF_INET;
ce_addr.sin_port = htons((unsigned short)SERVER_PORT);
ce_addr.sin_addr.s_addr = INADDR_ANY;
printf("Start connecting...\n");
if ( connect(sock_c, (struct sockaddr*)&ce_addr, sizeof(struct sockaddr_in)) == 1 ) { //サーバーに接続要求送信
printf("connect error\n");
close(sock_c);
return 1;
}
printf("Finish connect.\n");
transfer(sock_c); //通信
close(sock_c); //クローズ
}
サーバとクライアントともに、コンパイルは出来ました。
こちらとしては、while文によって文字列を繰り返し入力・送信出来るプログラムを想定していました。しかし、クライアント側は、文字列を入力してエンターキーを押したら、サーバ側に文字列が反映された(送信出来た)までは良かったものの、その後「Input Message here :」は表示されず、次の文字列を入力出来ずにそのまま動かなくなりました。恐らく、書いたプログラムに不備があるはずだと思っています。
どなたか、お力添え頂けると幸いです。アドバイスあれば是非お願いします。
0