hageking
@hageking

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

c++のソケット通信について

解決したいこと

C++のソケット通信で構造体を送受信する方法を教えてください。
ネットで調べても出てこないのでわかる方教えてくれると嬉しいです。

0

4Answer

まずは、構造体を使わない通信プログラムを書いて動かして、そのコードを示してくださいませんか?

0Like
server.cpp
#include <iostream>		//標準入出力
#include <sys/socket.h> //アドレスドメイン
#include <sys/types.h>	//ソケットタイプ
#include <arpa/inet.h>	//バイトオーダの変換に利用
#include <unistd.h>		//close()に利用
#include <string>		//string型

int main()
{

	//ソケットの生成
	int sockfd = socket(AF_INET, SOCK_STREAM, 0); //アドレスドメイン, ソケットタイプ, プロトコル
	if (sockfd < 0)
	{ //エラー処理

		std::cout << "Error socket:" << std::strerror(errno); //標準出力
		exit(1);											  //異常終了
	}

	//アドレスの生成
	struct sockaddr_in addr;					   //接続先の情報用の構造体(ipv4)
	memset(&addr, 0, sizeof(struct sockaddr_in));  // memsetで初期化
	addr.sin_family = AF_INET;					   //アドレスファミリ(ipv4)
	addr.sin_port = htons(1234);				   //ポート番号,htons()関数は16bitホストバイトオーダーをネットワークバイトオーダーに変換
	addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // IPアドレス,inet_addr()関数はアドレスの翻訳

	//ソケット登録
	if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
	{ //ソケット, アドレスポインタ, アドレスサイズ //エラー処理

		std::cout << "Error bind:" << std::strerror(errno); //標準出力
		exit(1);											//異常終了
	}

	//受信待ち
	if (listen(sockfd, SOMAXCONN) < 0)
	{ //ソケット, キューの最大長 //エラー処理

		std::cout << "Error listen:" << std::strerror(errno); //標準出力
		close(sockfd);										  //ソケットクローズ
		exit(1);											  //異常終了
	}

	while (1)
	{

		//接続待ち
		struct sockaddr_in get_addr;									  //接続相手のソケットアドレス
		socklen_t len = sizeof(struct sockaddr_in);						  //接続相手のアドレスサイズ
		int connect = accept(sockfd, (struct sockaddr *)&get_addr, &len); //接続待ちソケット, 接続相手のソケットアドレスポインタ, 接続相手のアドレスサイズ

		if (connect < 0)
		{ //エラー処理

			std::cout << "Error accept:" << std::strerror(errno); //標準出力
			exit(1);											  //異常終了
		}

		//受信
		char str[12];				   //受信用データ格納用
		recv(connect, str, 12, 0);	   //受信
		std::cout << str << std::endl; //標準出力

		//送信
		send(connect, str, 12, 0);	   //送信
		std::cout << str << std::endl; //標準出力

		//ソケットクローズ
		close(connect);
		// close(sockfd);
	}

	return 0;
}
client.cpp
#include <iostream> //標準入出力
#include <sys/socket.h> //アドレスドメイン
#include <sys/types.h> //ソケットタイプ
#include <arpa/inet.h> //バイトオーダの変換に利用
#include <unistd.h> //close()に利用
#include <string> //string型

struct a
{
	int a;
};


int main(){

	//ソケットの生成
	int sockfd = socket(AF_INET, SOCK_STREAM, 0); //アドレスドメイン, ソケットタイプ, プロトコル
	if(sockfd < 0){ //エラー処理

		std::cout << "Error socket:" << std::strerror(errno); //標準出力
		exit(1); //異常終了
	}

	//アドレスの生成
	struct sockaddr_in addr; //接続先の情報用の構造体(ipv4)
	memset(&addr, 0, sizeof(struct sockaddr_in)); //memsetで初期化
	addr.sin_family = AF_INET; //アドレスファミリ(ipv4)
	addr.sin_port = htons(1234); //ポート番号,htons()関数は16bitホストバイトオーダーをネットワークバイトオーダーに変換
	addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //IPアドレス,inet_addr()関数はアドレスの翻訳

	//ソケット接続要求
	connect(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)); //ソケット, アドレスポインタ, アドレスサイズ

	//データ送信
	char s_str[] = "HelloWorld!"; //送信データ格納用
	struct client k = {0};
	send(sockfd, s_str, 12, k); //送信
	std::cout << s_str << std::endl;

	//データ受信
	char r_str[12]; //受信データ格納用
	recv(sockfd, r_str, 12, 0); //受信
	std::cout << r_str << std::endl; //標準出力

	//ソケットクローズ
	close(sockfd);

	return 0;
}

これが構造体を使わずhelloworldを送信するプログラムです。
構造体aをサーバーに送信してそれをサーバーからクライアントに送信したいです。

0Like

構造体のアドレスとサイズを渡せばいいですよ。

サーバ側
                //受信
                struct a {
                    int a;
                } a;
                recv(connect, &a, sizeof(a), 0);           //受信
                std::cout << a.a << std::endl; //標準出力

                //送信
                send(connect, &a, sizeof(a), 0);           //送信
                std::cout << a.a << std::endl; //標準出力
クライアント側
        //データ送信
        struct a a = { 12345 };
        send(sockfd, &a, sizeof(a), 0); //送信
        std::cout << a.a << std::endl;

        //データ受信
        struct a b; //受信データ格納用
        recv(sockfd, &b, sizeof(b), 0); //受信
        std::cout << b.a << std::endl; //標準出力
0Like

Comments

  1. @hageking

    Questioner

    ありがとうございます。
    やってみます。

Your answer might help someone💌