🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

TCP

TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

Q&A

解決済

2回答

10530閲覧

ソケット通信でint型の数値の送受信を行いたい

mmmw

総合スコア23

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

TCP

TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

0グッド

0クリップ

投稿2019/10/28 08:09

編集2019/10/28 08:44

前提・実現したいこと

int型で処理を行うために,ソケット通信でint型の数値の送受信を行いたい

発生している問題・エラーメッセージ

送信前後で数値が変わってします。

C++

1//クライアント型 2int main() 3{ 4 5 6 //TCP 7 8 char server_ip_addr[32]; 9 10 int port_number; 11 12 13 14 // Windows Sockets仕様に関する情報を格納する構造体 15 16 WSADATA wsa_data; 17 18 // WinSockの初期化処理(Version 2.0) 19 20 if (WSAStartup(MAKEWORD(2, 0), &wsa_data) != 0) { 21 22 std::cerr << "Winsockの初期化失敗(WSAStartup)" << std::endl; 23 24 } 25 26 27 28 // ユーザ入力 29 30 std::cout << "接続先IPアドレスを入力してください(xxx.xxx.xxx.xxx)" << std::endl; 31 32 std::cin >> server_ip_addr; 33 34 std::cout << "ポート番号を入力してください" << std::endl; 35 36 std::cin >> port_number; 37 38 39 40 // sockaddr_in構造体の作成とポート番号、IPタイプの入力 41 42 struct sockaddr_in dst_addr; 43 44 memset(&dst_addr, 0, sizeof(dst_addr)); 45 46 dst_addr.sin_port = htons(port_number); // ポート番号 47 48 dst_addr.sin_family = AF_INET; // AF_INETはipv4を示す 49 50 51 52 // 引数は (1) Type(ipv4 or v6) (2) IPアドレスのテキスト形式 (3) IPアドレスのバイナリ形式【(2)→(3)に変換】 53 54 inet_pton(dst_addr.sin_family, server_ip_addr, &dst_addr.sin_addr.s_addr); 55 56 57 58 // AF_INETはipv4のIPプロトコル & SOCK_STREAMはTCPプロトコル 59 60 int dst_socket = socket(AF_INET, SOCK_STREAM, 0); 61 62 63 64 // 接続処理 65 66 if (connect(dst_socket, (struct sockaddr *) &dst_addr, sizeof(dst_addr))) { 67 68 std::cerr << "接続失敗(サーバIPアドレス" << server_ip_addr << "/接続先ポート番号" << port_number << std::endl; 69 70 exit(0); 71 72 } 73 74 75 76 std::cout << "接続完了(サーバIPアドレス" << server_ip_addr << "/接続先ポート番号" << port_number << std::endl << std::endl;; 77 78 79 80 81 82 char send_buf1[257]; 83 84 char recv_buf[257]; 85 86 int P = 5; 87 88 89 90 91 92 93 //TCP 94 95 96 // Packetの送信(SOCKET, Buffer, Datasize, 送信方法) 97 send_buf1[256] = (char)P; 98 99 100 101 send(dst_socket, send_buf1, 256, 0); 102 103 // Packetの受信 104 105 recv(dst_socket, recv_buf, 256, 0); 106 107 108 109 } 110 111 // 解放処理 112 113 closesocket(dst_socket); 114 115 116 117 // WinSockの終了処理 118 119 WSACleanup(); 120 121 122 123} 124 125

該当のソースコード

C++

1// サーバ側 WinSock2 2 3 4 5#include <stdio.h> 6 7#include <winsock2.h> 8 9#include <ws2tcpip.h> 10 11#include <iostream> 12 13 14 15int main() { 16 17 18 19 // ポート番号 20 21 int port_number = 12345; 22 23 24 25 // Windows Sockets仕様に関する情報を格納する構造体 26 27 WSADATA wsa_data; 28 29 30 31 // WinSockの初期化処理(Version 2.0) 32 33 if (WSAStartup(MAKEWORD(2, 0), &wsa_data) != 0) { 34 35 std::cerr << "Winsockの初期化失敗(WSAStartup)" << std::endl; 36 37 } 38 39 40 41 // サーバ側ソケット作成 42 43 int src_socket; 44 45 46 47 // sockaddr_in構造体の作成とポート番号、IPタイプの入力 48 49 struct sockaddr_in src_addr; 50 51 memset(&src_addr, 0, sizeof(src_addr)); 52 53 src_addr.sin_port = htons(port_number); 54 55 src_addr.sin_family = AF_INET; 56 57 src_addr.sin_addr.s_addr = htonl(INADDR_ANY); 58 59 60 61 // AF_INETはipv4のIPプロトコル & SOCK_STREAMはTCPプロトコル 62 63 src_socket = socket(AF_INET, SOCK_STREAM, 0); 64 65 66 67 // サーバ側のソケットを特定のIPアドレスとポートに紐付ける 68 69 bind(src_socket, (struct sockaddr *) &src_addr, sizeof(src_addr)); 70 71 72 73 // クライアント側のソケット設定 74 75 int dst_socket; 76 77 struct sockaddr_in dst_addr; 78 79 int dst_addr_size = sizeof(dst_addr); 80 81 82 83 // 接続の待受を開始する 84 85 listen(src_socket, 1); 86 87 88 89 // 送受信に使用するバッファ 90 91 char recv_buf1[257]; 92 93 char send_buf[257]; 94 95 int P; 96 97 98 // クライアントからの接続待ちループ関数 99 100 while (1) { 101 102 103 104 std::cout << "クライアントからの接続待ち" << std::endl; 105 106 107 108 // クライアントからの接続を受信する 109 110 dst_socket = accept(src_socket, (struct sockaddr *) &dst_addr, &dst_addr_size); 111 112 113 114 std::cout << "クライアントからの接続有り" << std::endl; 115 116 117 118 // 接続後の処理 119 120 while (1) { 121 122 //パケットの受信(recvは成功すると受信したデータのバイト数を返却。切断で0、失敗で-1が返却される 123 124 int recv1_result = recv(dst_socket, recv_buf1, sizeof(char) * 256, 0); 125 126 if (recv1_result == 0 || recv1_result == -1) { 127 128 status = closesocket(dst_socket); break; 129 130 } 131 132 133 P =(int)recv_buf1; 134 //P = atoi(&recv_buf1); 135 std::cout << P << std::endl; 136 137 138 139 // 結果を格納したパケットの送信 140 141 send(dst_socket, send_buf, sizeof(char) * 256, 0); 142 143 } 144 145 } 146 147 148 149 // WinSockの終了処理 150 151 WSACleanup(); 152 153 154 155 return 0; 156 157} 158 159

試したこと

char型でないとデータが送信できないので,一度クライアント側でchar型にし,サーバー側でint側にしている。

補足情報(FW/ツールのバージョンなど)

visual studio 2017

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

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

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

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

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

guest

回答2

0

C

1 int P = 5; 2 3 // Packetの送信(SOCKET, Buffer, Datasize, 送信方法) 4 send_buf1[256] = (char)&P;

これでは全然意図したとおりのデータは入りません。
&p は p のアドレスになりますから、send_buf1[256] には、5 ではない何かが書き込まれるだけです。
※そもそもキャストがおかしいので warning でるはずですが

しかもsend_buf1[0]~send_buf1[255] の中に何が入っているかは全くの偶然になります。
※デバッグレベルでコンパイルしているなら 0 埋めされているかも知れませんが、まったくの環境依存です

投稿2019/10/28 08:28

tacsheaven

総合スコア13703

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

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

mmmw

2019/10/28 08:33

ご指摘ありがとうございます。 今回の場合,int型の数値を送るためにはどのようにすればよいのでしょうか。
mmmw

2019/10/28 08:40

クライアント側 // Packetの送信(SOCKET, Buffer, Datasize, 送信方法) send_buf1[256] = (char)P; サーバー側 P =(int)recv_buf1; std::cout << P << std::endl; と変更した時 全く意味不明な数値が受信側で表示されました。
kaina

2019/10/28 08:58

いや、だからtacsheavenさんが「send_buf1[0]~send_buf1[255] の中に何が入っているかは全くの偶然になります。」って書いてありますやん。 なんでsend_buf1の先頭に代入しないの?send_buf1の初期化は行っているの?
tacsheaven

2019/10/28 09:17

その方法だと p > 255 の時に破綻しますね。てか、なんで send_buf1[0]~send_buf1[255] を使わないの? 送るデータの「末尾」に追加したって、そりゃ受け取る側は先頭から受け取るんだから意味不明のデータになるに決まってるでしょう。
guest

0

ベストアンサー

send_buf1[256] = (char)&P;

一体何を送ってるんでしょうか。

素直に、int値を文字列にして送りましょうよ

投稿2019/10/28 08:21

y_waiwai

総合スコア88038

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

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

mmmw

2019/10/28 08:28

クライアント側の // Packetの送信(SOCKET, Buffer, Datasize, 送信方法) send_buf1[256] = (char)&P; 部分でchar型に変換して送信しているつもりなのですが,どうでしょうか。 最終的にはデータ受信側で 5 を表示させたいです。
y_waiwai

2019/10/28 09:04

&P ってのは、Pのアドレスですよ
y_waiwai

2019/10/28 09:06

前にも言ったと思いますが、C言語の文法など、基礎からやり直しましょうよ。 あなたにはソケット通信はまだ無理です
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問