/*
ClientMusicSim.c
音楽プレーヤー(クライアント)
*/
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
//送信データ
typedef struct{
int in; //モード遷移指令の入力値
int id; //ユーザーID
char password[10]; //パスワード
}SendMessage;
//受信データ
typedef struct{
int mode; //モード
}RecvMessage;
//送受信データの初期化
void Init(SendMessage *send_data, RecvMessage *recv_data){
//ユーザーID:100、パスワード:adminとする
send_data->in = 0;
send_data->id = 100;
strcpy(send_data->password, "admin");
recv_data->mode = 0;
}
// モード出力
void Output(int result){
if (result == 0) {
printf("電源OFFモード\n");
} else if (result == 1) {
printf("アイドルモード\n");
} else if (result == 2) {
printf("再生モード\n");
} else if (result == 3) {
printf("一時停止\n");
} else {
printf("定義されていないモードです\n");
}
}
int main(void){
int sock; //ソケット変数
struct sockaddr_in server_addr; //サーバ側アドレス構造体
SendMessage send_data; //送信データ構造体の宣言
RecvMessage recv_data; //受信データ構造体の宣言
int count; //ループ回数
//送受信データの初期化
Init(&send_data, &recv_data);
// ソケット作成
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
//IPアドレスをローカルホスト(127.0.0.1)に設定
//ポート番号を12345に設定
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
server_addr.sin_port = htons(12345);
//コネクト処理を実行
connect(sock, (struct sockaddr *) &server_addr, sizeof(server_addr));
printf("0:電源ON/OFF 1:再生/一時停止 2:停止\n");
count = 1;
while(1){
//モード遷移指令の入力
printf("(%d) モード遷移指令の入力: ",count);
scanf("%d",&send_data.in);
//データ送信
send(sock, &send_data, sizeof(send_data), 0);
//データ受信
recv(sock, &recv_data, sizeof(recv_data), 0);
//モードの表示
Output(recv_data.mode);
count++;
}
//ソケットをクローズ
close(sock);
return 0;
}
/*
ServerMusicSim.c
音楽プレーヤー(サーバ)
*/
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
//モード定義
typedef enum{
MODE_POWER_OFF, //電源OFFモード
MODE_IDLE, //アイドルモード
MODE_PLAY, //再生モード
MODE_PAUSE //一時停止モード
}MODE;
//モード遷移指令
typedef enum{
ACT_POWER_ONOFF, //電源ON/OFF指令
ACT_PLAY, //再生指令
ACT_STOP //停止指令
}ACT;
//送信データ
typedef struct{
int mode; //モード遷移指令(受信)
}SendMessage;
//受信データ
typedef struct{
int in; //モード遷移指令の入力値
char password[10]; //パスワード
int id; //ユーザーID
}RecvMessage;
int gMode; //モード変数(グローバル)
void init(SendMessage *send_data, RecvMessage *recv_data){
//送受信データの設定
recv_data->in = 0;
recv_data->id = 100;
strcpy(recv_data->password, "admin");
send_data->mode = 0;
}
void modeset(int in){
switch(gMode){
// 電源OFFモードの場合
case MODE_POWER_OFF:
if (in == ACT_POWER_ONOFF)
gMode = MODE_IDLE;
break;
// アイドルモードの場合
case MODE_IDLE:
if (in == ACT_PLAY){
gMode = MODE_PLAY;
} else if (in == ACT_POWER_ONOFF){
gMode = MODE_POWER_OFF;
}
break;
// 再生モードの場合
case MODE_PLAY:
if (in == ACT_STOP){
gMode = MODE_IDLE;
} else if (in == ACT_PLAY){
gMode = MODE_PAUSE;
} else if (in == ACT_POWER_ONOFF){
gMode = MODE_POWER_OFF;
}
break;
// 一時停止モードの場合
case MODE_PAUSE:
if (in == ACT_STOP){
gMode = MODE_IDLE;
} else if (in == ACT_PLAY){
gMode = MODE_PLAY;
} else if (in == ACT_POWER_ONOFF){
gMode = MODE_POWER_OFF;
}
break;
default:
break;
}
}
int main()
{
int server_sock, client_sock; //ソケット変数の宣言
struct sockaddr_in server_addr, client_addr; //アドレス構造体の宣言
int client_len; //クライアント側アドレス構造体のサイズ
SendMessage send_data; //送信データ構造体の宣言
RecvMessage recv_data; //受信データ構造体の宣言
int count; //ループ回数
//データの初期化
init(&send_data, &recv_data);
//ソケットを作成
server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
// サーバ側のアドレス構造体の設定
// IPアドレスを任意、ポート番号を12345に設定
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(12345);
// バインド、リッスンを実行
bind(server_sock, (struct sockaddr *) &server_addr, sizeof(server_addr));
listen(server_sock, SOMAXCONN);
//クライアントからの接続要求を待機
client_len = sizeof(client_addr);
client_sock = accept(server_sock, (struct sockaddr *) &client_addr, &client_len);
count = 1;
while (1){
printf("(%d) ",count);
//クライアントからの受信メッセージ
int n=0;
if (n = recv(client_sock, &recv_data, sizeof(recv_data), 0) != sizeof(recv_data)){
return -1;
}
//IDとパスワードを確認し、一致した場合はモードを変更する
if (recv_data.id == 100 && strcmp(recv_data.password,"admin") == 0){
modeset(recv_data.in);
} else {
printf("IDかパスワードが一致しません\n");
//デバッグ用 受信データの出力
printf("モード遷移指令: %d \n",recv_data.in);
printf("パスワード: %s\n",recv_data.password);
printf("ユーザーID: %d\n",recv_data.id);
}
//モードをセットし、クライアントにモードを送信する
send_data.mode = gMode;
send(client_sock, &send_data, sizeof(send_data), 0);
count++;
}
//ソケットをクローズ
close(client_sock);
return 0;
}
以下の入力を実行した結果を図1に示す。
Copyright © ITmedia, Inc. All Rights Reserved.
組み込み開発の記事ランキング
コーナーリンク
よく読まれている編集記者コラム