型変換

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
にこよん
記事: 101
登録日時: 1年前
住所: 大阪府
連絡を取る:

型変換

#1

投稿記事 by にこよん » 1ヶ月前

winsock通信で数字を送りたいのですがchar型しか送受信できないので変換する必要があります
ただ、変換しても数字に戻した時に数がおかしくなる時があります
どのように改善すればいいでしょうか?

コード:

//エンコード時
	memcpy(press_data, &version, 1);							//バージョン情報をコピー(unsigned char)
	memcpy(&press_data[1], &id, 2);								//識別IDをコピー(short int)
	memcpy(&press_data[3], &m_data_size, 4);					//元データのサイズをコピー

//デコード時
	memcpy(&version, press_data, 1);								//バージョン情報をコピー
	memcpy(&id, &press_data[1], 2);									//識別IDをコピー
	memcpy(&m_data_size, &press_data[3], 4);						//元データのサイズをコピー

[環境]win10,visualstudio2017, VC++
最近は東方風アクションゲームを少しずつ作ってる人です
東方翠風燐FreeDownload⇒http://dxlib.o.oo7.jp/cgi/patio/read.cgi?no=212

box
記事: 1692
登録日時: 7年前

Re: 型変換

#2

投稿記事 by box » 1ヶ月前

登場している変数名の定義ぐらいは見せていただきたいです。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
にこよん
記事: 101
登録日時: 1年前
住所: 大阪府
連絡を取る:

Re: 型変換

#3

投稿記事 by にこよん » 1ヶ月前

ご指摘ありがとうございます
どこまでお伝えすればいいのかが分からないので言っていただけると助かります
(最初からすべての部分をのせると読みにくそうだったので省略しました)
定義したものではなく関数の引数なのでどのように書けばいいのかわからず....
このあたりで大丈夫でしょうか?

コード:

//データを64進数文字列に圧縮変換する
class STR_ENCODE {
	uLong m_data_size;						//データのサイズ
	uLong m_press_size;						//圧縮後のデータのサイズ
	Bytef *m_buffer;						//データを保存するメモリのポインタ
	Bytef *m_press_buffer;					//圧縮データを保存するメモリのポインタ
	unsigned int m_write_size;				//書き込み中のサイズ
public:
	//コンストラクタ
	STR_ENCODE(int size);
	//デトラクタ
	~STR_ENCODE();
	//保存するデータをメモリにコピーする
	void wcpy(void const* Src, unsigned int Size);
	//データを圧縮して取得する
	int write(unsigned char version, short int id, char press_data[]);//←エンコードのはこいつ
};

//64進数文字列からデータに展開変換する
class STR_DECODE {
	uLong m_data_size;						//データのサイズ
	uLong m_press_size;						//圧縮後のデータのサイズ
	Bytef *m_buffer;						//データを保存するメモリのポインタ
	Bytef *m_press_buffer;					//圧縮データを保存するメモリのポインタ
	unsigned int m_write_size;				//書き込み中のサイズ
public:
	//コンストラクタ
	STR_DECODE(char press_data[], int size, unsigned char *version, short int *id);//←デコードはこいつ
	//デトラクタ
	~STR_DECODE();
	//読み込んだデータをコピーする
	void rcpy(void *Src, unsigned int Size);
	//データを展開して取得する
	int read();
};

コード:

//デコード関数の内容↓
STR_DECODE::STR_DECODE(char press_data[],int size, unsigned char *version, short int *id) {							//コンストラクタ
	memcpy(version, press_data, 1);									//バージョン情報をコピー
	memcpy(id, &press_data[1], 2);									//識別IDをコピー
	memcpy(&m_data_size, &press_data[3], 4);						//元データのサイズをコピー
	//version = press_data[0];									//バージョン情報をコピー
	//id = press_data[1];									//識別IDをコピー
	//m_data_size = press_data[3];						//元データのサイズをコピー

	//m_data_size = ((long)press_data[6] << 24) | ((long)press_data[5] << 16) | ((long)press_data[4] << 8) | (long)press_data[3];

	m_press_size = size -7;
	for (int i =0; i < m_press_size; i++)
		press_data[i] = press_data[i + 7];							//7バイト分前に詰める

	m_buffer = (Bytef*)malloc(m_data_size);							//保存するデータより十分大きいメモリを確保
	if (!m_buffer) {
		WSA_ERR("メモリの確保に失敗しました");						//エラーメッセージ
		return;
	}

	m_press_buffer = (Bytef*)malloc(m_press_size);					//圧縮後のデータを保存するメモリを確保する
	if (!m_press_buffer) {
		WSA_ERR("メモリの確保に失敗しました");						//確保に失敗すればエラーメッセージ
		return;
	}
	m_write_size = 0;												//書き込み中サイズの初期化

	for (unsigned long i = 0; i <  m_press_size; i++) m_press_buffer[i] = press_data[i] + 128;
};

最近は東方風アクションゲームを少しずつ作ってる人です
東方翠風燐FreeDownload⇒http://dxlib.o.oo7.jp/cgi/patio/read.cgi?no=212

かずま

Re: 型変換

#4

投稿記事 by かずま » 1ヶ月前

にこよん さんが書きました:
1ヶ月前
winsock通信で数字を送りたいのですがchar型しか送受信できないので変換する必要があります
ただ、変換しても数字に戻した時に数がおかしくなる時があります
「おかしくなる時があります」だけでは情報不足です。
実際にどんな値を送信したら、受信した値がどうなったかを書きましょう。

winsock通信ということですが、受信の
n = recv(sock, press_data, m, 0);
で、n や m は 7以上になっていますか?

アバター
にこよん
記事: 101
登録日時: 1年前
住所: 大阪府
連絡を取る:

Re: 型変換

#5

投稿記事 by にこよん » 1ヶ月前

nは普通にサイズを表してくれています
mはこのように書いています

コード:

//データ通信で使用できる最大サイズ
#define MAX_DATA_SIZE				262144

コード:

	char buf[MAX_DATA_SIZE];
	memset(buf, 0, sizeof(buf));
	int n = recv(sock, buf, sizeof(buf), 0);
てっきりmemcpyを使うこと自体が間違いなのかと思っていたのですが、そうではないのでしょうか?


一応送受信のプログラムを貼っておきます
必要なければスルーでお願いします
(見ずらい貼り方ですみません)
//ヘッダ

コード:

class SERVER {
	SOCKET sock_lobby;			//通信要請を受け取るソケット
	sockaddr_in addr;			//ロビーのアドレス情報
	SOCKET sock;				//クライアントとの通信を行うソケット
	sockaddr_in client_addr;	//クライアント情報
	SOCKET udp_sock;
	sockaddr_in udp_addr;		//ロビーのアドレス情報
public:
	//コンストラクタ
	SERVER();
	//サーバーのスタートアップ処理
	int Stert();
	//クライアントからの通信を受け取る
	int Accept();
	//データを送信する
	int Send(const TCHAR *data, const int size);
	//データを受信する
	int Recv(char data[]);
	//UDP通信のスタートアップ処理
	int UDPstert();
	//データを送信する
	int UDPsend(const char data[]);
	//データを受信する
	int UDPrecv(char data[1024]);
	//UDP通信を終了する
	int UDPend();
};

class CLIENT {
	struct sockaddr_in server_addr;
	SOCKET sock;

public:
	//コンストラクタ
	CLIENT();
	//データをサーバーに送信する
	int Send(const TCHAR *data, int size);
	//データをサーバーから受信する
	int Recv(char data[]);
};
//cpp

コード:

SERVER::SERVER() {


}

int SERVER::Stert() {
	sock_lobby = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);		//ソケットの作成
	if (sock_lobby == INVALID_SOCKET) {
		WSA_ERR("ソケットの作成に失敗しました(%d)", WSAGetLastError());
		return COMM_LIB_ERROR;
	}
	else AddTempLog("ロビーソケットを作成しました");

	bool yes = true;							//1が登録されたポインタを作成
	setsockopt(sock_lobby, SOL_SOCKET, SO_REUSEADDR, (const char *)&yes, sizeof(yes));		//TIME_WAIT状態への対策(ソケットオプションの設定

	addr.sin_family = AF_INET;					//ソケットの設定をする
	addr.sin_port = htons(PORT);				//使用するポート
	addr.sin_addr.S_un.S_addr = INADDR_ANY;		//接続するアドレス

	if (bind(sock_lobby, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
		WSA_ERR("ローカルアドレスとソケットの関連付けに失敗しました(%d)", WSAGetLastError());
		return COMM_LIB_ERROR;
	}
	else AddTempLog("ローカルアドレスとソケットの関連付けが完了しました");

	u_long val = 1;								//ノンブロッキング(非同期通信)に設定する
	ioctlsocket(sock_lobby, FIONBIO, &val);

	if (listen(sock_lobby, 5) != 0) {			//TCPクライアントからの接続要求を待てる状態にする
		WSA_ERR("ソケットをリッスン状態にできませんでした(%d)", WSAGetLastError());
		return COMM_LIB_ERROR;
	}
	else AddTempLog("ソケットを通信受付状態にしました");

	AddTempLog("ロビーソケットの初期化が正常に終了しました port=%d", PORT);
	return COMM_LIB_NO_ERROR;
}

int SERVER::Accept() {
	int len = sizeof(client_addr);								//TCPクライアントからの接続要求を受け付ける
	sock = accept(sock_lobby, (struct sockaddr *)&client_addr, &len);
	if (sock == INVALID_SOCKET) {								//ソケットの値が正常ではない
		if (WSAGetLastError() != WSAEWOULDBLOCK) {				//要請がない場合ではなかったら
			WSA_ERR("クライアントからの接続に失敗しました(%d)", WSAGetLastError());
			return COMM_LIB_ERROR;
		}
	}
	else {														//接続要請があれば
		hostent *host = gethostbyaddr((const char *)&client_addr.sin_addr, sizeof(addr.sin_addr), AF_INET);
		if (host == NULL) {										//失敗したらエラーを表示して終了
			WSA_ERR("ホスト情報の取得に失敗しました(%d)", WSAGetLastError());
			return COMM_LIB_ERROR;
		}
		AddServerLog("		accepted connection from [%s], ip=%s, port=%d", host->h_name, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
		return 1;
	}
	return COMM_LIB_NO_ERROR;
}

int SERVER::Recv(char data[]) {
	char buf[MAX_DATA_SIZE];
	memset(buf, 0, sizeof(buf));
	int n = recv(sock, buf, sizeof(buf), 0);
	if (n < 0) {
		if (WSAGetLastError() != WSAEWOULDBLOCK) {			//何らかのエラーが発生している
			WSA_ERR("データの受信に失敗しました(%d)", WSAGetLastError());
			return COMM_LIB_ERROR;
		}
	}
	else if (n != 0) {				//データが届いたら
		AddTempLog("データを受信しました-%d「%.64s」", n, buf);
		sprintf_s(data, 1024, "%s", buf);
		return n;
	}
	return COMM_LIB_NO_ERROR;
}

int SERVER::Send(const TCHAR *data, int size) {
	if (send(sock, data, /*strlen(data)*/size, 0) < 1) {
		WSA_ERR("データの送信に失敗しました(%d)", WSAGetLastError());
		closesocket(sock);			//TCPセッションの終了
		memset(&sock, 0, sizeof(sock));
		return COMM_LIB_ERROR;
	}
	else AddTempLog("データを送信しました「%.64s」", data);

	closesocket(sock);			//TCPセッションの終了
	memset(&sock, 0, sizeof(sock));
	return COMM_LIB_NO_ERROR;
}





CLIENT::CLIENT() {

}

int CLIENT::Recv(char data[]) {
	char buf[MAX_DATA_SIZE];
	memset(buf, 0, sizeof(buf));
	int n = recv(sock, buf, sizeof(buf), 0);
	if (n < 0) {
		if (WSAGetLastError() != WSAEWOULDBLOCK) {			//何らかのエラーが発生している
			WSA_ERR("データの受信に失敗しました(%d)", WSAGetLastError());
			return COMM_LIB_ERROR;
		}
	}
	else if (n != 0) {				//データが届いたら
		AddTempLog("データを受信しました-%d「%.64s」", n, buf);
		closesocket(sock);			//TCPセッションの終了
		memset(&sock, 0, sizeof(sock));
		sprintf_s(data, n, "%s", buf);
		return n;
	}
	return COMM_LIB_NO_ERROR;
}

int CLIENT::Send(const TCHAR *data, int size) {
	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);		//ソケットの作成
	if (sock == INVALID_SOCKET) {
		WSA_ERR("ソケットの作成に失敗しました(%d)", WSAGetLastError());
		return COMM_LIB_ERROR;
	}
	else AddTempLog("ソケットを作成しました");


	server_addr.sin_family = AF_INET;					//ソケットの設定をする
	server_addr.sin_port = htons(PORT);					//使用するポート
	hostent *host = gethostbyname(host_name);		//リリース時にはホストIPを使う

	if (host == NULL) {
		WSA_ERR("サーバー情報がありません");
		return COMM_LIB_ERROR;
	}
	server_addr.sin_addr.S_un.S_addr = *(unsigned int *)host->h_addr_list[0];		//サーバーIPアドレスを取得する
	AddTempLog("サーバー情報の取得に成功しました");

	if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) != 0) {//サーバに接続を試みる
		WSA_ERR("サーバーに接続できませんでした(%d)", WSAGetLastError());
		return COMM_LIB_ERROR;
	}
	else AddTempLog("サーバーに接続しました");

	if (send(sock, data, size, 0) < 1) {
		WSA_ERR("データの送信に失敗しました(%d)", WSAGetLastError());
		return COMM_LIB_ERROR;
	}
	else AddTempLog("データの送信に成功しました");
	return COMM_LIB_NO_ERROR;
}
最近は東方風アクションゲームを少しずつ作ってる人です
東方翠風燐FreeDownload⇒http://dxlib.o.oo7.jp/cgi/patio/read.cgi?no=212

アバター
にこよん
記事: 101
登録日時: 1年前
住所: 大阪府
連絡を取る:

Re: 型変換

#6

投稿記事 by にこよん » 1ヶ月前

数は正確には
2177584206
になっています
送る前(エンコード前)の正しい数は4です

※この数は最初の7バイトを含まないデータサイズです
最近は東方風アクションゲームを少しずつ作ってる人です
東方翠風燐FreeDownload⇒http://dxlib.o.oo7.jp/cgi/patio/read.cgi?no=212

かずま

Re: 型変換

#7

投稿記事 by かずま » 1ヶ月前

version, id, m_data_size のすべての値を書いてください。

例えば、version = 'A', id = 63, m_data_size = 4 だとすると、
press_data は、{ 0x41, 0x3f, 0x00, 0x04, 0x00, 0x00, 0x00 } の
7バイトになり、それが送信され、受信されると
buf にその値が入ります。
それを data にコピーするところで、sprintf_s(data, 1024, "%s", buf);
または、sprintf_s(data, n, "%s", buf); を使っていますが、
これだと、data には { 0x41, 0x3f, 0x00 } しかコピーされません。

なぜなら、sprintf の "%s" は文字列を扱うので、
'\0' までしか参照しないからです。

id = 258 の場合、press_data は、
{ 0x41, 0x02, 0x01, 0x04, 0x00, 0x00, 0x00 } となって、
{ 0x41, 0x02, 0x01, 0x04, 0x00 } が data にコピーされます。

受信データをすべてコピーしたいのなら、
memcpy(data, buf, 1024); または
memcpy(data, buf, n); にしましょう。

アバター
にこよん
記事: 101
登録日時: 1年前
住所: 大阪府
連絡を取る:

Re: 型変換

#8

投稿記事 by にこよん » 1ヶ月前

ご回答ありがとうございます
テストではこのようにしています
version = 1, id = 1
(version = '1'と間違えているわけではなく1を入れています)


> 受信データをすべてコピーしたいのなら、
> memcpy(data, buf, 1024); または
> memcpy(data, buf, n); にしましょう。

2ヶ所下のほうに書き換えて実行してみたのですが、結果は変わらずでした...
最近は東方風アクションゲームを少しずつ作ってる人です
東方翠風燐FreeDownload⇒http://dxlib.o.oo7.jp/cgi/patio/read.cgi?no=212

アバター
にこよん
記事: 101
登録日時: 1年前
住所: 大阪府
連絡を取る:

Re: 型変換

#9

投稿記事 by にこよん » 1ヶ月前

最初のところにエンコード等のコードを乗せていなかったので乗せます
必要なければスルーでお願いしますm(__)m
h

コード:

#ifndef ZLIB_H
#pragma comment(lib, "zlib.lib")				//Zlibをリンクする
#include <zlib.h>								//Zlibをインクルードする
#endif

//データを64進数文字列に圧縮変換する
class STR_ENCODE {
	uLong m_data_size;						//データのサイズ
	uLong m_press_size;						//圧縮後のデータのサイズ
	Bytef *m_buffer;						//データを保存するメモリのポインタ
	Bytef *m_press_buffer;					//圧縮データを保存するメモリのポインタ
	unsigned int m_write_size;				//書き込み中のサイズ
public:
	//コンストラクタ
	STR_ENCODE(int size);
	//デトラクタ
	~STR_ENCODE();
	//保存するデータをメモリにコピーする
	void wcpy(void const* Src, unsigned int Size);
	//データを圧縮して取得する
	int write(unsigned char version, short int id, char press_data[]);
};

//64進数文字列からデータに展開変換する
class STR_DECODE {
	uLong m_data_size;						//データのサイズ
	uLong m_press_size;						//圧縮後のデータのサイズ
	Bytef *m_buffer;						//データを保存するメモリのポインタ
	Bytef *m_press_buffer;					//圧縮データを保存するメモリのポインタ
	unsigned int m_write_size;				//書き込み中のサイズ
public:
	//コンストラクタ
	STR_DECODE(char press_data[], int size, unsigned char *version, short int *id);
	//デトラクタ
	~STR_DECODE();
	//読み込んだデータをコピーする
	void rcpy(void *Src, unsigned int Size);
	//データを展開して取得する
	int read();
};
cpp

コード:

STR_ENCODE::STR_ENCODE(int size) : m_data_size(size) {				//コンストラクタ
	m_buffer = (Bytef*)malloc(m_data_size);							//保存するデータより十分大きいメモリを確保
	if (!m_buffer) WSA_ERR("メモリの確保に失敗しました");			//エラーメッセージ

	uLong press_buffer_size = compressBound(m_data_size);			//圧縮に必要なサイズを計算
	if (m_data_size > press_buffer_size) {							//計算結果があっているか確認する
		WSA_ERR("press size error (%lu -> %lu)", m_data_size, press_buffer_size);						//あっていなければエラーメッセージ
	}

	m_press_buffer = (Bytef*)malloc(press_buffer_size);				//圧縮後のデータを保存するメモリを確保する
	if (!m_press_buffer) WSA_ERR("メモリの確保に失敗しました");		//確保に失敗すればエラーメッセージ
	m_write_size = 0;												//書き込み中サイズの初期化
};
STR_ENCODE::~STR_ENCODE() {						//デストラクタ
	free(m_buffer);								//確保したメモリの解放
	free(m_press_buffer);						//確保したメモリの開放
}
void STR_ENCODE::wcpy(void const* Src, unsigned int Size) {
	if (m_write_size + Size > m_data_size) {			//保存データが確保したメモリのデータより大きかったら
		WSA_ERR("エンコードするデータが大きすぎます");	//エラーメッセージ
		return;											//終了
	}

	memcpy(m_buffer + m_write_size, Src, Size);			//データをメモリにコピーする
	m_write_size += Size;								//保存した分だけメモリを進める
}
int STR_ENCODE::write(unsigned char version, short int id, char press_data[]) {				//データを圧縮してファイルに書き込む
	if (m_write_size != m_data_size) {
		WSA_ERR("保存データのサイズが一致しませんでした");			//エラーメッセージ
		WSA_ERR("詳細 : %lu -> %lu", m_write_size, m_data_size);	//詳細をエラーメッセージ
		return COMM_LIB_ERROR;										//エラーで終了する									
	}

	uLongf press_size;
	int z_err = compress2(m_press_buffer, &press_size, m_buffer, m_data_size, Z_BEST_SPEED);		//データの圧縮
	if (z_err != Z_OK) {									//エラーコードが返ってきたら
		WSA_ERR("データの圧縮に失敗しました");					//エラーメッセージ
		switch (z_err) {
		case Z_MEM_ERROR:
			WSA_ERR("Z_MEM_ERROR エラーが発生しました");
			break;
		case Z_BUF_ERROR:
			WSA_ERR("Z_BUF_ERROR メモリに十分な空き容量がありません");
			break;
		case Z_STREAM_ERROR:
			WSA_ERR("Z_STREAM_ERROR 圧縮レベルが不明です");
			break;

		default:
			WSA_ERR("Z_ERROR 不明なエラーが発生しました");
			break;
		}
		return COMM_LIB_ERROR;									//エラーで終了する
	}

	for (unsigned long i = 0; i < press_size; i++) press_data[i] = m_press_buffer[i] - 128;		//圧縮したデータを変換コピーする

	for (int i = press_size - 1; i >= 0; i--)
		press_data[i + 7] = press_data[i];						//最初に7バイトの空きを作る
	memcpy(press_data, &version, 1);							//バージョン情報をコピー
	memcpy(&press_data[1], &id, 2);								//識別IDをコピー
	memcpy(&press_data[3], &m_data_size, 4);					//元データのサイズをコピー

	//press_data[0] = version;					//バージョン情報をコピー
	//press_data[1] = id;							//識別IDをコピー
	//press_data[3] = (char)m_data_size;				//元データのサイズをコピー
	return int(press_size) + 7;
}


STR_DECODE::STR_DECODE(char press_data[],int size, unsigned char *version, short int *id) {							//コンストラクタ
	memcpy(version, press_data, 1);									//バージョン情報をコピー
	memcpy(id, &press_data[1], 2);									//識別IDをコピー
	memcpy(&m_data_size, &press_data[3], 4);						//元データのサイズをコピー
	//version = press_data[0];									//バージョン情報をコピー
	//id = press_data[1];									//識別IDをコピー
	//m_data_size = press_data[3];						//元データのサイズをコピー

	//m_data_size = ((long)press_data[6] << 24) | ((long)press_data[5] << 16) | ((long)press_data[4] << 8) | (long)press_data[3];

	m_press_size = size - 7;
	for (int i =0; i < m_press_size; i++)
		press_data[i] = press_data[i + 7];							//7バイト分前に詰める

	m_buffer = (Bytef*)malloc(m_data_size);							//保存するデータより十分大きいメモリを確保
	if (!m_buffer) {
		WSA_ERR("メモリの確保に失敗しました");						//エラーメッセージ
		return;
	}

	m_press_buffer = (Bytef*)malloc(m_press_size);					//圧縮後のデータを保存するメモリを確保する
	if (!m_press_buffer) {
		WSA_ERR("メモリの確保に失敗しました");						//確保に失敗すればエラーメッセージ
		return;
	}
	m_write_size = 0;												//書き込み中サイズの初期化

	for (unsigned long i = 0; i <  m_press_size; i++) m_press_buffer[i] = press_data[i] + 128;
};
STR_DECODE::~STR_DECODE() {						//デストラクタ
	free(m_buffer);								//確保したメモリの解放
	free(m_press_buffer);						//確保したメモリの開放
}
void STR_DECODE::rcpy(void *Src, unsigned int Size) {
	if (m_write_size >= m_data_size) {
		WSA_ERR("データサイズが確保分を超えました");	//エラーメッセージ
		return;										//戻る
	}

	memcpy(Src, m_buffer + m_write_size, Size);		//メモリからデータをコピーする
	m_write_size += Size;							//保存した分だけメモリを進める
}
int STR_DECODE::read() {
	int z_err = uncompress(m_buffer, &m_data_size, m_press_buffer, m_press_size);	//データを展開
	if (z_err != Z_OK) {
		WSA_ERR("データの展開に失敗しました");						//エラーメッセージ
		switch (z_err) {
		case Z_MEM_ERROR:
			WSA_ERR("Z_MEM_ERROR エラーが発生しました");
			break;
		case Z_BUF_ERROR:
			WSA_ERR("Z_BUF_ERROR メモリに十分な空き容量がありません");
			break;
		case Z_DATA_ERROR:
			WSA_ERR("Z_DATA_ERROR データが破損しています");
			break;
		default:
			WSA_ERR("Z_ERROR 不明なエラーが発生しました");
			break;
		}
		return COMM_LIB_ERROR;									//エラーで終了する
	}

	return COMM_LIB_NO_ERROR;									//正常終了
}
最近は東方風アクションゲームを少しずつ作ってる人です
東方翠風燐FreeDownload⇒http://dxlib.o.oo7.jp/cgi/patio/read.cgi?no=212

かずま

Re: 型変換

#10

投稿記事 by かずま » 1ヶ月前

コード:

void dump(void *vp, int n)
{
	unsigned char *p = (unsigned char *)vp;
	for (int i = 0; i < n; i++) printf(" %02x", p[i]);
	putchar('\n');
}
上記の関数を追加し、
send(sock, data, size, 0); の前に dump(data, 7); を
recv(sock, buf, sizeof(buf), 0); の後に dump(buf, 7); を
入れて、実行結果を教えてください。

アバター
にこよん
記事: 101
登録日時: 1年前
住所: 大阪府
連絡を取る:

Re: 型変換

#11

投稿記事 by にこよん » 1ヶ月前

サーバー側(recv
f8 81 4b 4e 4c cb 81
クライアント側(send
64 fa 5d 00 13 00 00
でした

ほんとですね全くデータが違う....
いまいち適切なデータの確認方法が分かってなかったので見方が分かりましたm(__)m

ただ、送る直前と受け取った直後なのでデータが変わっている理由が分からないです...
TCP通信だからデータが破損ではない...?
最近は東方風アクションゲームを少しずつ作ってる人です
東方翠風燐FreeDownload⇒http://dxlib.o.oo7.jp/cgi/patio/read.cgi?no=212

アバター
にこよん
記事: 101
登録日時: 1年前
住所: 大阪府
連絡を取る:

Re: 型変換

#12

投稿記事 by にこよん » 1ヶ月前

もしかして、マルチバイト文字セットを使っているのが原因だったりしますでしょうか...?

それか下のやつを定義していることとか...?
#define _WINSOCK_DEPRECATED_NO_WARNINGS //警告を消す
最近は東方風アクションゲームを少しずつ作ってる人です
東方翠風燐FreeDownload⇒http://dxlib.o.oo7.jp/cgi/patio/read.cgi?no=212

かずま

Re: 型変換

#13

投稿記事 by かずま » 1ヶ月前

version = 1, id = 1, m_data_szie = 4 なら
送信データは、01 01 00 04 00 00 00 となるはずです。

Visuual Studioe 2017 を使っているのなら、
ブレークポイントを設定し、ステップ実行で変数の値の変化を確認しながら、
デバッグできるはずです。

そういうことができないのなら、printf をあちこちに入れて、
変数の値の変化がどうなっているのかを確認してください。
デバッグの基本です。

アバター
にこよん
記事: 101
登録日時: 1年前
住所: 大阪府
連絡を取る:

Re: 型変換

#14

投稿記事 by にこよん » 1ヶ月前

ブレークポイントからデバッグはやっていたのですが
1バイト目の中身が\x1と表示されそれ以降が見れなかったのでどうすればいいのかわからずにいろいろ調べていました

とりあえず教えて頂いた関数と中に入るべき数の正解の数を利用して原因を探ってみますm(__)m
最近は東方風アクションゲームを少しずつ作ってる人です
東方翠風燐FreeDownload⇒http://dxlib.o.oo7.jp/cgi/patio/read.cgi?no=212

アバター
にこよん
記事: 101
登録日時: 1年前
住所: 大阪府
連絡を取る:

Re: 型変換 (解決)

#15

投稿記事 by にこよん » 1ヶ月前

原因は教えていただいたsprintf_sでの文字コピーと
decode関数で引数を直接編集していることのようでした

dump関数はこのまま残しておいて、また使えるようにしておきます
かずまさん、ご丁寧に教えていただきありがとうございましたm(__)m
最近は東方風アクションゲームを少しずつ作ってる人です
東方翠風燐FreeDownload⇒http://dxlib.o.oo7.jp/cgi/patio/read.cgi?no=212

返信

“C言語何でも質問掲示板” へ戻る