至急(6月29日まで)お願い致します。
大学の課題でTCPクライアントとサーバで通信を行い、座標データを送受信してオセロを行うというものをやっています。
<自分で埋めなければならない場所>
課題①→自身の座標情報(onArea.x , onArea.y)の値を送信文字列(StrBuf)に格納する処理
課題②→受信文字列(StrBuf)の値を自身の座標情報(onArea.x , onArea.y)に格納する処理
<プログラムの仕様>
- クライアントが先攻、サーバが後攻でゲームが進む。
- サーバ・クライアント間では、相手がそれぞれ「盤面のどこに石を置いたか」を互いに通信により送受信する。
- 受信した情報をもとにそれぞれが、turn_stone()関数を用いて盤面の石を返すものとする。
- 「盤面のどこに石を置いたか」の情報は、onArea オブジェクトに格納される。
- onArea オブジェクトのメンバーには、onArea.y(縦の位置)、 onArea.x(横の位置)が格納される(onArea.y
とonArea.x 値の範囲は0 から7 まで)。
6. クライアント・サーバ間のデータ送受信ではStrBuf を使用する。
上記の処理を行うプログラミングを書くのですが、クライアント側ではオセロはできるもののうまく送信できず(もしくは受信)サーバ側でオセロができません。文字列に値を格納する際、0にならないよう1を加算して格納することと、int型からchar型への格納なのでキャストを行うことはわかっています。
また、実際に課題①には
StrBuf[1] = (char)(onArea.x+1);
StrBuf[2] = (char)(onArea.y + 1);
と書きました。これは一応動作しています。
課題②には
onArea.x=(int)(StrBuf[1]-1);
onArea.y=(int)(StrBuf[2]-1);
や
onArea.x=StrBuf[1]-1;
onArea.y=StrBuf[2]-2;
など書いてみたのですがうまく動きません。
何が間違っているのかもわからないため、アドバイスをいただきく質問致しました。
TCPクライアントのプログラムを添付致しますので、どなたかお力を貸していただけないでしょうか。
ちなみに、サーバ側も課題①と課題②を書くスペースがありますが、クライアント側で書いたものとおなじものが入ります。
<TCPクライアントプログラム>
#include <winsock.h> //Windows用ソケットライブラリ用
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Othello.h"
#pragma comment(lib,"wsock32.lib") //WinSockライブラリをリンク
#pragma warning( disable: 4996 ) // scanfとmemcpy実行の際のwarningを非表示にする
#define MAX_BUFF_12A 1024 // バッファの長さ
int PortNum = 10010; //ポート番号
char hostname[50] = "127.0.0.1"; //サーバのアドレス
// メイン関数
int main( void )
{
char StrBuf[MAX_BUFF_12A + 1] ;
char szHost[MAX_BUFF_12A + 1];
SOCKET data_socket;
WSADATA wsaData;
SOCKADDR_IN server;
HOSTENT *hostEnt;
int rVal;
WORD wVersionRequested;
unsigned int addr;
coordinate onArea;
//ソケットの初期化(ウィンドウズ用WinSockの初期化)
wVersionRequested = MAKEWORD( 1, 1 );
rVal = WSAStartup( wVersionRequested, &wsaData ); //初期化の関数
if(rVal != 0 || wsaData.wVersion != wVersionRequested) { //初期化のエラー
printf("エラー:ソケット初期化・・・終了します\n");
WSACleanup();
return(-1);
}
//ソケット生成(TCPソケット)
data_socket = socket( AF_INET, SOCK_STREAM, 0 ) ; // ソケット生成の関数
if( data_socket < 0 ) {
printf("エラー:ソケット生成・・・終了します\n");
WSACleanup();
return(-1);
}
// サーバ情報の取得 strcpy( szHost, hostname ); //サーバ名(名前またはIP)をszHostへコピー if( isalpha( szHost[0] ) ) { // 名前の場合 hostEnt = gethostbyname( szHost ); //DNSへ問合せ } else { // IPアドレスの場合 addr = inet_addr( szHost ); hostEnt = gethostbyaddr( (char*)&addr, 4, AF_INET ); } if( hostEnt == NULL ) { printf("エラー:アドレスを解決できない [%s]\n・・・終了します\n", szHost); WSACleanup(); return(-1); } printf("サーバを起動させて下さい\n"); printf("起動したらEnterキーを押す"); getchar(); printf("******クライアントの起動*****\n"); // サーバ接続のための初期化 memset( &server, 0, sizeof(server) ); memcpy( &(server.sin_addr), hostEnt->h_addr, hostEnt->h_length ); server.sin_family = hostEnt->h_addrtype; server.sin_addr.s_addr = *(( unsigned long*)hostEnt -> h_addr ); //サーバアドレス server.sin_port = htons( (unsigned short) PortNum ); // サーバのポート番号の設定 // サーバへ接続を試みる(connect関数) printf("サーバ[%s]へ接続中...\n", szHost ); if( connect( data_socket,(struct sockaddr*)&server, sizeof(server) ) == SOCKET_ERROR) { printf("エラー:サーバへの接続(connect)\n...終了します\n"); WSACleanup(); return(-1); } printf("%sに接続完了\n", szHost ); // ここからメインルーチン init(); printf("クライアント側が先攻(O)\n"); onArea.x = onArea.y = 0; while(total_fill < grid_size*grid_size){ // 先攻 // ターンの初期化 turn =O_BLACK; rturn = O_WHITE; do{ // 座標情報を受け付ける printf ("縦を入力(1-8): "); scanf ("%d",&onArea.y); printf ("横を入力(1-8): "); scanf ("%d",&onArea.x); onArea.x--; onArea.y--; // 空白のマスか確認 }while(check_empty(onArea)); // 石を返す turn_stone(onArea); // 結果の出力 output(); // データをサーバに送信 // 課題① // 課題① send( data_socket, StrBuf, (int)strlen(StrBuf), 0 ); // ターンの変更 turn =O_WHITE; rturn = O_BLACK; printf("相手の思考待ち\n"); // データの受信 rVal = recv( data_socket, StrBuf, (int)strlen(StrBuf), 0 ); //受信(recv関数) StrBuf[rVal] = '\0'; //受信したデータ(文字列)の最後にNULL文字付加 if( rVal == SOCKET_ERROR || rVal == 0 ) { //受信時エラー(または切断) printf("エラー:相手からの切断されました\n・・・終了します\n"); break; } // 課題② // 課題② // 石を返す turn_stone(onArea); output(); } // ソケット終了処理 closesocket( data_socket ); //ソケットのクローズ WSACleanup(); //ソケットの破棄 printf("\n\nEnterキーを1,2回押してプログラム終了"); getchar(); //プログラム一時停止(キー入力待ち) getchar(); //プログラム一時停止(キー入力待ち) return(0);
}
回答1件
あなたの回答
tips
プレビュー