前提・実現したいこと
C言語の勉強のためにソケット間通信を使用したDBのようなアプリを作成しています。
クライアント実行時にテーブル名を引数として渡して、サーバー側が該当ファイルを検索しクライアント側へ返すというものです。
発生している問題・エラーメッセージ
サーバー側で取得した結果をクライアントでrecvするんですが第三引数のlenの長さによってエラーになります。
以下は後述するソースDBClient.cの22行目辺りです。
NG
int resultLen = recv(sock, result, 3000, 0); printf("%s\n", result); // a printf("%d", resultLen); // -1を返す
OK
int resultLen = recv(sock, result, 35, 0); printf("%s\n", result); // 指定したファイルの内容 printf("%d", resultLen); //35
質問させていただきたいことは
1.第三引数が大きくなりすぎるとエラーになってしまう理由
2.サーバー側から受け取るサイズがわからない状態でこの引数にどの値を指定するべきでしょうか
自分で思いつくのは事前にサイズを別のソケット通信で受け取っておくぐらいしか思い浮かびませんが他にいい方法はありますか
該当のソースコード
DBClient.c
C
1#include <stdio.h> 2#include <WinSock2.h> 3 4int main(int argc, char *argv[]) 5{ 6 WSADATA w; 7 struct sockaddr_in server; 8 char buf[256]; 9 char *result; 10 11 WSAStartup(MAKEWORD(2, 0), &w); 12 13 int sock = socket(AF_INET, SOCK_STREAM, 0); 14 server.sin_addr.s_addr = inet_addr("127.0.0.1"); 15 server.sin_port = htons(9999); 16 server.sin_family = AF_INET; 17 18 strcpy(buf, argv[1]); 19 20 connect(sock, (struct sockaddr *)&server, sizeof(server)); 21 send(sock, buf, sizeof(buf), 0); 22 int resultLen = recv(sock, result, 3000, 0); 23 printf("%s\n", result); 24 printf("%d", resultLen); 25 26 closesocket(sock); 27 WSACleanup; 28 29 return 0; 30}
DBServer.c
C
1#include <stdio.h> 2#include <WinSock2.h> 3#include "tableSelect.h" 4 5int main() 6{ 7 WSADATA w; 8 struct sockaddr_in server, client; 9 char buf[20]; 10 char *result; 11 12 WSAStartup(MAKEWORD(2, 0), &w); 13 int sock = socket(AF_INET, SOCK_STREAM, 0); 14 server.sin_addr.s_addr = INADDR_ANY; 15 server.sin_port = htons(9999); 16 server.sin_family = AF_INET; 17 18 bind(sock, (struct sockaddr *)&server, sizeof(server)); 19 listen(sock, 1); 20 int len = sizeof(client); 21 int sock2 = accept(sock, (struct sockaddr *)&client, &len); 22 23 recv(sock2, buf, sizeof(buf), MSG_PEEK); 24 result = tableSelect(buf); 25 printf("%s", result); 26 send(sock2, result, 3000, 0); 27 28 closesocket(sock); 29 closesocket(sock2); 30 31 WSACleanup(); 32 33 return 0; 34}
tableSelect.c
C
1#include <stdio.h> 2#include <string.h> 3#include "tableSelect.h" 4 5char *tableSelect(char tblName[20]) 6{ 7 static char result[3000]; 8 FILE *fp; 9 char filePath[256]; 10 int chr; 11 int i = 0; 12 sprintf(filePath, "data/%s/%s.csv", tblName, tblName); 13 14 fp = fopen(filePath, "r"); 15 while ((chr = fgetc(fp)) != EOF) 16 { 17 result[i] = chr; 18 i++; 19 } 20 21 fclose(fp); 22 return result; 23}
実行に成功した時のイメージ
D:\C practice\C_Database\Client>client.exe T_USER UserId,Name,deleteFLag 1,Shimo,0 3000
試したこと
Client側のresultをポインタではなくてchar型配列(char result[3000])を使用すれば第三引数が3000であってもファイルの内容がクライアントへ渡せることは確認できました。
ただファイルの内容は大きいので複数箇所でサイズの大きいメモリを作るのは良くないかと思いポインタで解決したいと思っています。
補足情報(FW/ツールのバージョンなど)
Windows 10 64bit
gcc 9.2.0
回答2件
あなたの回答
tips
プレビュー