質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

4109閲覧

サーバとクライアントの三目並べ

Asahi_1115

総合スコア13

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2017/06/19 07:01

編集2017/06/23 06:52

サーバとクライアント間で接続を行って、三目並べ(勝敗判定なし)を実行するプログラムを作ってます。接続まではできたのですが、二次元配列の使い方がわからず、下記のような実行結果までたどり着けません。どのように書き足せばよいのでしょうか。

<サーバ側>
クライアントからの接続待ち
123
1---
2---
3---
クライアントへデータを送信してください
行ナンバー:1
列ナンバー:1

123
1s--
2---
3---
クライアントからのデータ待ち
[1]クライアントからのデータ(行) = 2
[1]クライアントからのデータ(列) = 2

<クライアント側>

123
1---
2---
3---

サーバからの受信待ち
[1]サーバからのデータ(行) = 1
[1]サーバからのデータ(列) = 2

123
1s--
2---
3---
サーバへデータを送信してください
行ナンバー:2
列ナンバー:2

123
1s--
2-c-
3---

※石を置くたびshow_plane()関数を実行して盤の内容を表示する

  • サーバ側

define

1include <stdio.h> 2include <winsock2.h> 3define BUF_LEN 2//入出力バッファサイズ 4 5void show_plane(void); 6 char plane[4][5] = {" 123","1---","2---","3---"}; 7int main() 8 { 9 WSADATA wsaData; 10 SOCKET sock0; 11 struct sockaddr_in addr; 12 struct sockaddr_in client; 13 int len; 14 SOCKET sock; 15 16//char buf[BUF_LEN];//入出力バッファ 17int buf[BUF_LEN];//入出力バッファ 18 19// winsock2の初期化 20WSAStartup(MAKEWORD(2, 0), &wsaData); 21 22// ソケットの作成 23sock0 = socket(AF_INET, SOCK_STREAM, 0); 24 25// ソケットの設定(アドレス構造体の設定) 26addr.sin_family = AF_INET;//インターネットを使用する 27addr.sin_port = htons(12345);//サーバ(自分自身)のポート番号 28addr.sin_addr.S_un.S_addr = INADDR_ANY;//IPアドレスすべての値指定 29 30//ソケットのディスクリプタとアドレス構造体を結びつける 31bind(sock0, (struct sockaddr *)&addr, sizeof(addr)); 32 33// TCPクライアントからの接続要求を待てる状態にする(待ちクライアント数指定) 34listen(sock0,1); 35 36// TCPクライアントからの接続要求を受け付ける 37printf("クライアントからの接続待ち\n"); 38 len = sizeof(client); 39 sock = accept(sock0, (struct sockaddr *)&client, &len); 40 41//送受信処理 42int cnt = 1; 43 char inputdata[4]; 44 do{ 45 printf("クライアントへデータを送信してください\n"); 46 memset(buf, 0, sizeof(buf));//送受信バッファ0クリア 47 48//キーボードから行列を入力 49printf("行ナンバー:"); 50gets(inputdata); 51 buf[0] = atoi(inputdata); 52 printf("列ナンバー:"); 53gets(inputdata); 54 buf[1] = atoi(inputdata); 55 send(sock, (char*)buf, sizeof(buf), 0);//送信 データint型配列だが通信はchar型で 56//(数値型はサイズがシステムで異なるので) 57 58printf("クライアントからのデータ待ち\n"); 59 memset(buf, 0, sizeof(buf)); 60 recv(sock, (char*)buf, sizeof(buf), 0);//受信 データint型配列だが通信はchar型で 61printf("[%d]クライアントからのデータ(行)= %d\n", cnt, buf[0]); 62 printf("[%d]クライアントからのデータ(列)= %d\n", cnt, buf[1]); 63 64cnt++; 65 } while (buf[0]!= 99);//クライアントから行99受信したら終了 66 67// TCPセッションの終了 68closesocket(sock); 69 70// winsock2の終了処理 71WSACleanup(); 72 return 0; 73 } 74 void show_plane(void){ 75 printf("\n"); 76 for(int i = 0; j < 4; i++){ 77 78printf("%c",plane[i][j]); 79 } 80 printf("\n"); 81 82} 83
  • クライアント側

efine

1define _WINSOCK_DEPRECATED_NO_WARNINGS 2include <stdio.h> 3include <winsock2.h> 4define BUF_LEN 2//入出力バッファサイズ 5 6void show_plane(void); 7 char plane[4][5] = {" 123","1---","2---","3---"}; 8int main() 9 { 10 WSADATA wsaData; 11 struct sockaddr_in server; 12 SOCKET sock; 13 //char buf[BUF_LEN];//入出力バッファ 14int buf[BUF_LEN];//入出力バッファ 15 16// winsock2の初期化 17WSAStartup(MAKEWORD(2, 0), &wsaData); 18 19// ソケットの作成 20sock = socket(AF_INET, SOCK_STREAM, 0); 21 22// 接続先指定用アドレス構造体の準備 23server.sin_family = AF_INET;//インターネット使用 24server.sin_port = htons(12345);//接続先ポート番号 25server.sin_addr.S_un.S_addr = inet_addr("*.*.*.*");//接続先IPアドレス 26 27// サーバに接続 28connect(sock, (struct sockaddr *)&server, sizeof(server)); 29 30//受信送信処理 31int cnt=1; 32 char inputdata[4]; 33 do{ 34 memset(buf, 0, sizeof(buf));//送受信バッファ0クリア 35printf("サーバからのデータ受信待ち\n"); 36 recv(sock, (char*)buf, sizeof(buf), 0);//受信 データint型配列だが通信はchar型で 37printf("[%d]サーバからのデータ(行)= %d\n", cnt,buf[0]); 38 printf("[%d]サーバからのデータ(列)= %d\n", cnt, buf[1]); 39 40printf("サーバへデータを送信してください\n"); 41 memset(buf, 0, sizeof(buf));//送受信バッファ0クリア 42 43//キーボードから行列を入力 44printf("行ナンバー:"); 45gets(inputdata); 46 buf[0] = atoi(inputdata); 47 printf("列ナンバー:"); 48gets(inputdata); 49 buf[1] = atoi(inputdata); 50 send(sock, (char*)buf, sizeof(buf), 0);;//送信 データint型配列だが通信はchar型で 51cnt++; 52 } while (buf[0] != 99);//行99送信した場合、終了 53// TCPセッションの終了 54closesocket(sock); 55 56// winsock2の終了処理 57WSACleanup(); 58 return 0; 59 } 60 void show_plane(void){ 61 printf("\n"); 62 for(int i = 0; j < 4; i++){ 63 64printf("%c",plane[i][j]); 65 } 66 printf("\n"); 67 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2017/06/19 07:08

タグを修正して下さい。また、コードが正しく囲えていないので修正して下さい。
guest

回答2

0

send前にplane配列へ格納すれば良いでしょうかね。
あとsend前、recv後にshow_planeも呼ばないとだめかもですね。

C

1plane[buf[0]][buf[1]] = 'S'; 2show_plane(); 3send(sock, (char*)buf, sizeof(buf), 0); 45recv(sock, (char*)buf, sizeof(buf), 0); 6show_plane();

それからshow_planeの処理がよろしくないですね。
plane配列の各行はNUL文字で終わっているので、文字ではなく文字列として出力した方が効率良いでしょう。

c

1void show_plane(void){ 2 printf("\n"); 3 for(int i = 0; j < 4; i++){ 4 printf("%s\n",plane[i]); 5 } 6 printf("\n"); 7}

他にも指摘すべき点は多々あるかもしれませんが、とりあえず気づいたところです。

投稿2017/06/26 00:32

ttyp03

総合スコア16996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

うーん…学校の課題か何かかい?
不明点のコードのレベルが低すぎて教えることにあまり気乗りしませんが…
まあ個人的なプログラムかもしれませんしね。

C

1int row = buf[0]; 2int col = buf[1]; 3 4plane[row][col] = 's'; // 又は 'c'。 5show_plane();

あえて最小のコードにしています。
これを送受信前後に挟めばいいでしょう。

show_planeにも不具合があるし、入力内容のエラー処理がないという致命的な問題があります。
が、とりあえず二次元配列の取り扱いというならこれだけでいいでしょうかね。

投稿2017/06/23 08:09

haru666

総合スコア1591

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問