前提・実現したいこと
ソケット通信プログラムで測定データの送受信を行いたい
受信側で受信した測定データが0になってしまう
発生している問題・エラーメッセージ
クライアント側で受け取り表示するデータが0になってしまう
該当のソースコード
C++
1 2//クライアント側 3 4 5 6 7VOID DisplayFrame( PBYTE pBuf, DWORD dwSize ) 8{ 9 //TCP 10 11 char server_ip_addr[32]; 12 13 int port_number; 14 15 16 17 // Windows Sockets仕様に関する情報を格納する構造体 18 19 WSADATA wsa_data; 20 21 // WinSockの初期化処理(Version 2.0) 22 23 if (WSAStartup(MAKEWORD(2, 0), &wsa_data) != 0) { 24 25 std::cerr << "Winsockの初期化失敗(WSAStartup)" << std::endl; 26 27 } 28 29 30 31 // ユーザ入力 32 33 std::cout << "接続先IPアドレスを入力してください(xxx.xxx.xxx.xxx)" << std::endl; 34 35 std::cin >> server_ip_addr; 36 37 std::cout << "ポート番号を入力してください" << std::endl; 38 39 std::cin >> port_number; 40 41 42 43 // sockaddr_in構造体の作成とポート番号、IPタイプの入力 44 45 struct sockaddr_in dst_addr; 46 47 memset(&dst_addr, 0, sizeof(dst_addr)); 48 49 dst_addr.sin_port = htons(port_number); // ポート番号 50 51 dst_addr.sin_family = AF_INET; // AF_INETはipv4を示す 52 53 54 55 // 引数は (1) Type(ipv4 or v6) (2) IPアドレスのテキスト形式 (3) IPアドレスのバイナリ形式【(2)→(3)に変換】 56 57 inet_pton(dst_addr.sin_family, server_ip_addr, &dst_addr.sin_addr.s_addr); 58 59 60 61 // AF_INETはipv4のIPプロトコル & SOCK_STREAMはTCPプロトコル 62 63 int dst_socket = socket(AF_INET, SOCK_STREAM, 0); 64 65 66 67 // 接続処理 68 69 if (connect(dst_socket, (struct sockaddr *) &dst_addr, sizeof(dst_addr))) { 70 71 std::cerr << "接続失敗(サーバIPアドレス" << server_ip_addr << "/接続先ポート番号" << port_number << std::endl; 72 73 exit(0); 74 75 } 76 77 78 79 std::cout << "接続完了(サーバIPアドレス" << server_ip_addr << "/接続先ポート番号" << port_number << std::endl << std::endl;; 80 81 82 83 84 85 char send_buf1[256]; 86 87 char recv_buf[256]; 88 89 90 91 92 93 TCHAR szFrame[200]; 94 DWORD i = 0; 95 96 while ( i<dwSize) 97 { 98 BYTE ucSensor = pBuf[i+2]; 99 SHORT shSize = pBuf[i+6]; 100 101 // skip rest of header 102 i += 8; 103 104 PDWORD pFC = (PDWORD)(&pBuf[i]); 105 PFLOAT pPno = (PFLOAT)(&pBuf[i+4]); 106 107 _sntprintf( szFrame, _countof(szFrame), _T("%2d %d %+011.6f %+011.6f %+011.6f %+011.6f %+011.6f %+011.6ff\r"), 108 ucSensor, *pFC, pPno[0], pPno[1], pPno[2], pPno[3], pPno[4], pPno[5] ); 109 tstring sF = tstring(szFrame); 110 if (g_bScroll) 111 sF += tstring(_T("\n")); 112 113 114 115 //TCP 116 117 // Packetの送信(SOCKET, Buffer, Datasize, 送信方法) 118 send_buf1[256] = pPno[5]; 119 120 send(dst_socket, send_buf1, 256, 0); 121 122 // Packetの受信 123 124 recv(dst_socket, recv_buf, 256, 0); 125 126 127 128 AddMsg( sF ); 129 130 i += shSize; 131 } 132 133 // 解放処理 134 135 closesocket(dst_socket); 136 137 138 139 // WinSockの終了処理 140 141 WSACleanup(); 142} 143 144 145 146 147/////////////////////////////////////////////////////////////////////// 148/////////////////////////////////////////////////////////////////////// 149 150 151 152 153// サーバ側 WinSock2 154 155 156 157#include <stdio.h> 158 159#include <winsock2.h> 160 161#include <ws2tcpip.h> 162 163#include <iostream> 164 165 166 167int main() { 168 169 170 171 // ポート番号 172 173 int port_number = 12345; 174 175 176 177 // Windows Sockets仕様に関する情報を格納する構造体 178 179 WSADATA wsa_data; 180 181 182 183 // WinSockの初期化処理(Version 2.0) 184 185 if (WSAStartup(MAKEWORD(2, 0), &wsa_data) != 0) { 186 187 std::cerr << "Winsockの初期化失敗(WSAStartup)" << std::endl; 188 189 } 190 191 192 193 // サーバ側ソケット作成 194 195 int src_socket; 196 197 198 199 // sockaddr_in構造体の作成とポート番号、IPタイプの入力 200 201 struct sockaddr_in src_addr; 202 203 memset(&src_addr, 0, sizeof(src_addr)); 204 205 src_addr.sin_port = htons(port_number); 206 207 src_addr.sin_family = AF_INET; 208 209 src_addr.sin_addr.s_addr = htonl(INADDR_ANY); 210 211 212 213 // AF_INETはipv4のIPプロトコル & SOCK_STREAMはTCPプロトコル 214 215 src_socket = socket(AF_INET, SOCK_STREAM, 0); 216 217 218 219 // サーバ側のソケットを特定のIPアドレスとポートに紐付ける 220 221 bind(src_socket, (struct sockaddr *) &src_addr, sizeof(src_addr)); 222 223 224 225 // クライアント側のソケット設定 226 227 int dst_socket; 228 229 struct sockaddr_in dst_addr; 230 231 int dst_addr_size = sizeof(dst_addr); 232 233 234 235 // 接続の待受を開始する 236 237 listen(src_socket, 1); 238 239 240 241 // 送受信に使用するバッファ 242 243 char recv_buf1[257], recv_buf2[257]; 244 245 char send_buf[257]; 246 247 248 249 // クライアントからの接続待ちループ関数 250 251 while (1) { 252 253 254 255 std::cout << "クライアントからの接続待ち" << std::endl; 256 257 258 259 // クライアントからの接続を受信する 260 261 dst_socket = accept(src_socket, (struct sockaddr *) &dst_addr, &dst_addr_size); 262 263 264 265 std::cout << "クライアントからの接続有り" << std::endl; 266 267 268 269 // 接続後の処理 270 271 while (1) { 272 273 274 275 int status; 276 277 278 279 //パケットの受信(recvは成功すると受信したデータのバイト数を返却。切断で0、失敗で-1が返却される 280 281 int recv1_result = recv(dst_socket, recv_buf1, sizeof(char) * 256, 0); 282 283 if (recv1_result == 0 || recv1_result == -1) { 284 285 status = closesocket(dst_socket); break; 286 287 } 288 289 //std::cout << atoi(recv_buf1) << std::endl; ..... ※ 290 std::cout << strtol(recv_buf1,NULL,0) << std::endl; 291 292 send(dst_socket, send_buf, sizeof(char) * 256, 0); 293 294 } 295 296 } 297 298 299 300 // WinSockの終了処理 301 302 WSACleanup(); 303 304 305 306 return 0; 307 308} 309
試したこと
サーバー側ソースコードで※のところにatoi や strtolを試してみた
補足情報(FW/ツールのバージョンなど)
visual C++
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/10/25 02:15
2019/10/25 02:22
2019/10/25 02:30
2019/10/25 02:56