質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
87.20%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Visual C++

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

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

解決済

C言語 winsock sendデータを送ると文字化けする クライアントはRuby

kazuyakazuya
kazuyakazuya

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Visual C++

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

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。

4回答

0評価

1クリップ

3924閲覧

投稿2019/09/08 01:39

編集2022/01/12 10:58

6時間格闘した末に分からなかったので解決方法またはヒントをお願いします。

winsock(C言語)でサーバープログラムを作りました。
クライアントはRubyで作りました。(エンコーディングの話はあとで・・・)

内容としては

string

1 サーバーがクライアントが接続してくるまで待ち受ける 2  クライアントがサーバーへ接続すると、サーバー側でコマンドを打てるようになる。 3  打ったコマンド(サーバー)の実行結果をクライアントへ引き渡す 4 クライアント側で表示

#起こっている状況

サーバーサイド

c

#include <stdio.h> #include <winsock2.h> int main(void) { WSADATA wsaData; SOCKET sock0; SOCKET sock; struct sockaddr_in addr; struct sockaddr_in client; //ポート設定 int len; int port; printf("ポートを指定してください。\n"); scanf_s("%d", &port, 16); printf("指定されたポート番号は・・・%d\n", port); WSAStartup(MAKEWORD(2, 0), &wsaData); //Winsockの初期化 sock0 = socket(AF_INET, SOCK_STREAM, 0); // ソケット設定の構造体の設定 addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.S_un.S_addr = INADDR_ANY; bind(sock0, (struct sockaddr*) & addr, sizeof(addr)); listen(sock0, 5); int n = 1; //接続回数変数初期化 while (1) { len = sizeof(client); //sock = accept(sock0, (struct sockaddr*) & client, &len); if ((sock = accept(sock0, (struct sockaddr*) & client, &len)) < 0) { perror("エラーが発生しました。"); exit(1); }else { printf("接続に成功しました。これは%d回目です。\n", n); } //コマンドを送る char cmd[128]; printf("コマンドを入力してください。"); scanf_s("%s",&cmd,128); FILE *fp; if((fp=_popen(cmd,"r"))== NULL){ perror("エラーが発生しました。・・・"); } char buf[128]; while (fgets(buf,sizeof(buf), fp) != NULL) { send(sock, buf, sizeof(buf), 0); } _pclose(fp); closesocket(sock); n++; //カウント1プラス } WSACleanup(); //winsockの終了 return 0; }

クライアントサイド(注意 Rubyです。)

ruby

require 'socket' sock = TCPSocket.open("localhost","55555") while cmd = sock.gets#1行ずつコマンド実行結果を受け取る。 puts cmd #putsで表示させる。 end sock.close

イメージ説明
tasklistを実行させた結果です。

見てのとおり文字化けしています。
クライアントサイドで文字化けしている。
RubyではデフォルトでUTF-8なので
ASCIIにできないかと試行錯誤したのですが
参考記事
chrメソッドを使った方法
一通り試しましたがダメでした・・・。

だが、本当にクライアントサイドに問題があるのか
ということで

c

while (fgets(buf, sizeof(buf), fp) != NULL) { send(sock, "hello",5, 0);←ここ }

send関数で渡すデータをコマンド実行結果ではなく
hello文字列を送ったところ

ruby

hellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohellohello

文字化けせずに表示されます。
さらに

c

char mojiretu[] = "HelloWorld"; send(sock,mojiretu,sizeof(mojiretu),0);

実行結果

ruby

HelloWorld

文字化けせずに表示できていることから
Rubyクライアントサイドに問題があるのではなく

c

char buf[128]; while (fgets(buf,sizeof(buf), fp) != NULL) { send(sock, buf, sizeof(buf), 0); }

これに問題があるのかと思うのですが・・・。

fgets関数
イメージ説明
ファイルポインタが指すストリームからbuf配列へ
データを格納しているのだと思うのですが
それでも、なぜ文字化けが起こるのかがわかりません。

本当にfgetsらへんが原因なのか
クライアントサイドのエンコードに問題があるのか・・・

分からないので教えてください。

#追記
回答で指摘をいただいた
sizeを76にした結果です。
イメージ説明

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Visual C++

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

Socket.IO

Socket.IOはNode.js上で動くライブラリであり、すべてのブラウザとモバイルデバイスでリアルタイムのアプリを作動させる事を目的としています。