6時間格闘した末に分からなかったので解決方法またはヒントをお願いします。
winsock(C言語)でサーバープログラムを作りました。
クライアントはRubyで作りました。(エンコーディングの話はあとで・・・)
内容としては
string
11 サーバーがクライアントが接続してくるまで待ち受ける 22 クライアントがサーバーへ接続すると、サーバー側でコマンドを打てるようになる。 33 打ったコマンド(サーバー)の実行結果をクライアントへ引き渡す 44 クライアント側で表示
#起こっている状況
サーバーサイド
c
1#include <stdio.h> 2#include <winsock2.h> 3 4int main(void) { 5 6 WSADATA wsaData; 7 SOCKET sock0; 8 SOCKET sock; 9 struct sockaddr_in addr; 10 struct sockaddr_in client; 11 //ポート設定 12 int len; 13 int port; 14 printf("ポートを指定してください。\n"); 15 scanf_s("%d", &port, 16); 16 printf("指定されたポート番号は・・・%d\n", port); 17 18 WSAStartup(MAKEWORD(2, 0), &wsaData); //Winsockの初期化 19 20 sock0 = socket(AF_INET, SOCK_STREAM, 0); 21 // ソケット設定の構造体の設定 22 addr.sin_family = AF_INET; 23 addr.sin_port = htons(port); 24 addr.sin_addr.S_un.S_addr = INADDR_ANY; 25 26 bind(sock0, (struct sockaddr*) & addr, sizeof(addr)); 27 28 listen(sock0, 5); 29 30 int n = 1; //接続回数変数初期化 31 while (1) { 32 len = sizeof(client); 33 //sock = accept(sock0, (struct sockaddr*) & client, &len); 34 if ((sock = accept(sock0, (struct sockaddr*) & client, &len)) < 0) { 35 perror("エラーが発生しました。"); 36 exit(1); 37 }else { 38 printf("接続に成功しました。これは%d回目です。\n", n); 39 } 40 41 //コマンドを送る 42 char cmd[128]; 43 printf("コマンドを入力してください。"); 44 scanf_s("%s",&cmd,128); 45 FILE *fp; 46 if((fp=_popen(cmd,"r"))== NULL){ 47 perror("エラーが発生しました。・・・"); 48 } 49 50 char buf[128]; 51 while (fgets(buf,sizeof(buf), fp) != NULL) { 52 send(sock, buf, sizeof(buf), 0); 53 } 54 55 _pclose(fp); 56 closesocket(sock); 57 n++; //カウント1プラス 58 } 59 WSACleanup(); //winsockの終了 60 61 62 return 0; 63}
クライアントサイド(注意 Rubyです。)
ruby
1require 'socket' 2sock = TCPSocket.open("localhost","55555") 3 4while cmd = sock.gets#1行ずつコマンド実行結果を受け取る。 5puts cmd #putsで表示させる。 6end 7 8sock.close 9
見てのとおり文字化けしています。
クライアントサイドで文字化けしている。
RubyではデフォルトでUTF-8なので
ASCIIにできないかと試行錯誤したのですが
参考記事
chrメソッドを使った方法
一通り試しましたがダメでした・・・。
だが、本当にクライアントサイドに問題があるのか
ということで
c
1while (fgets(buf, sizeof(buf), fp) != NULL) { 2 send(sock, "hello",5, 0);←ここ 3 }
send関数で渡すデータをコマンド実行結果ではなく
hello文字列を送ったところ
ruby
1hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello
文字化けせずに表示されます。
さらに
c
1char mojiretu[] = "HelloWorld"; 2 send(sock,mojiretu,sizeof(mojiretu),0);
実行結果
ruby
1HelloWorld
文字化けせずに表示できていることから
Rubyクライアントサイドに問題があるのではなく
c
1char buf[128]; 2 while (fgets(buf,sizeof(buf), fp) != NULL) { 3 send(sock, buf, sizeof(buf), 0); 4 }
これに問題があるのかと思うのですが・・・。
fgets関数
ファイルポインタが指すストリームからbuf配列へ
データを格納しているのだと思うのですが
それでも、なぜ文字化けが起こるのかがわかりません。
本当にfgetsらへんが原因なのか
クライアントサイドのエンコードに問題があるのか・・・
分からないので教えてください。
#追記
回答で指摘をいただいた
sizeを76にした結果です。
c
1char buf[5]; 2 while (fgets(buf, sizeof(buf), fp) != NULL) { 3 char* e = buf; 4 send(sock, e,sizeof(e), 0); 5 printf(buf); 6 }
回答4件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/08 04:59