rshに関連してどなたか教えて下さい。
rsh-clientをC言語で書くには、具体的にどうしたらよいのでしょう?
例えば、
(1)socketをオープン。
(2)port=514でconnectを確立。
(3)sendで、"0\0"、ローカルユーザ、リモートユーザ、コマンドを送信。
(4)recvで受信。
とやっているのですが、毎回(3)まではエラーがなく、(4)で-1が返ってきます。私の理解が根本的に間違っているのかも知れません。
同じコマンドを、コマンドプロンプトからのrsh.exeでは実行可能です。
諸般の理由で、WindowsからLinux上のアプリを動かすのに、どうしてもCのコードの中にrshの機能を埋め込んで使いたのです。HTTP-clientのCのソースコードはよく見かけるし、自分でも書いていますが、rsh-clientは見たことがありません。
閉じた系で使うため、セキュリティ管理等は不要なので、使い慣れたrshが有り難いのですが...
是非よろしくお願いします。
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
>そもそもrsh-clientの機能を実現するにはどのように書くのが一般的なんでしょうか?
一般的かどうか分かりませんが個人的な意見として
rsh-clientを自力実装することをあきらめ、
windows付属のrshをCreateProcessで起動し、プロセスの標準入出力をリダイレクトする。
という方法が良いのでは思われます。
参考情報
他のプロセスの出力を取得する
http://www.h4.dion.ne.jp/~fht/wptips/readprc.html
No.3
- 回答日時:
1,エラーコードが10054なのでWSAECONNRESET (10054) ですね。
>? 意味 : ピアによって接続がリセットされました。
ピア(サーバー)からの強制切断なので、送信しているデータは形式/内容ともに正しいものですか?
※)rshをethealでパケットキャプチャしながら実行して
rshの通信プロトコルを調べてみてください。
2,提示コードではコンパイルが通りません。
3,sendの戻り値のチェックが提示コードでは抜けています。
sendの戻値として-1の時があります。
4,以下の内容は手元の環境でwindows付属のrshを試してみた結果です。
手元の環境でwindows付属のrshコマンドを実行してみたところ、
rsh接続時に2つソケット(標準入出力用と標準エラー用)を作っています。
そして最初に標準エラー用のソケットの送信元ポート番号にNULL終端を付加しsendしています。
提示されたコードは最初に送信データとして"0\0"を送っていますが、
エラー用の送信元ポート番号を送る必要があるのではないのでしょうか?
以下のコードでソケットの送信元ポート番号を取得できます。
1,ローカル変数を2つ追加。
SOCKADDR_IN local;
int len;
2,iRC=send(sock,"0\0",2,0);の部分を以下のように変更。
len = sizeof(local);
/*ソケットの送信元ポート番号を取得*/
getsockname(sock,(const struct sockaddr*)&local,&len);
sprintf(t,"%u\0",ntohs(local.sin_port));
iRC=send(sock,t,strlen(t)+1,0);
以上、ご参考まで。
この回答への補足
たびたびすいません。
ご指摘に従って書き換えましたが、やはりrecvのところで-1が返ってきます。
コマンドとしては、取り敢えず"ls -l"を与えており、Windows付属のrsh.exeではちゃんと実行できます。
当方のコーディングは、根本的に間違っている可能性があります。
そもそもrsh-clientの機能を実現するにはどのように書くのが一般的なんでしょうか?
No.2
- 回答日時:
recv関数の戻り値が-1(SOCKET_ERROR)なので、サーバー側からの異常切断(RST)またはエラーだと思われます。
どのエラーなのかはWSAGetLastError関数で取得できますので確認してみてください。
例)
int n = recv(sock,buf,1024,0);
int code = WSAGetLastError();
Windows ソケットのエラー コード、値、および意味
http://support.microsoft.com/kb/819124/ja
recv Function
http://msdn.microsoft.com/en-us/library/ms740121 …
WSAGetLastError
http://msdn.microsoft.com/en-us/library/ms741580 …
この回答への補足
もう少し具体的に書きますと、書きのようにコーディングしています。
実際にやってみると、エラーコード10054が返ってきました。
----で囲んだ辺りの書き方が悪いのかも知れません。
引き続きアドバイスをお願いします。
int Exec_RSH(char *sCommand,char *sRet_str)
{ struct hostent *pHost;
WSADATA wsaData;
WORD wVersionRequired=0x0101;
SOCKADDR_IN addr;
SOCKET sock;
DWORD dwIP;
u_short PORT_NO=514;
int i=0,iRC=0;
char t[128],buf[4096];
int bFlag=1;
*sRet_str='\0';
if((WSAStartup(wVersionRequired,&wsaData))!=CLIENT_NO_ERROR) return(WSAGetLastError());
sock=socket(PF_INET,SOCK_STREAM,0);
if(sock==INVALID_SOCKET) return(-1);
if((dwIP=inet_addr(MY_HOST1))==INADDR_NONE){
if((pHost=gethostbyname(MY_HOST1))==NULL) return(-2);
dwIP=*((DWORD*)(pHost->h_addr));
}
addr.sin_family=AF_INET;
addr.sin_port=htons(PORT_NO);
addr.sin_addr.s_addr=dwIP;
if(connect(sock,(const struct sockaddr*)&addr,sizeof(addr))==SOCKET_ERROR) return(-3);
/*------------------------------------------------------*/
iRC=send(sock,"0\0",2,0);
strcpy(t,LOCAL_USER);
iRC=send(sock,t,strlen(t)+1,0);
strcpy(t,REMOTE_USER);
iRC=send(sock,t,strlen(t)+1,0);
strcpy(t,sCommand);
iRC=send(sock,t,strlen(t)+1,0);
/*------------------------------------------------------*/
while(bFlag){
i=recv(sock,buf,NNN-1,0);
if(i==0) break;
if(i==SOCKET_ERROR) return(WSAGetLastError());
buf[i]='\0';
strcat(sRet_str,buf);
}
closesocket(sock);
WSACleanup();
return(0);
}
No.1
- 回答日時:
はじめまして。
1,ビルド環境はwindows/linuxどちらですか?
winsockの場合はソケット操作を行う前にWSAStartupで初期化する必要がありますが。
2,文中のエラーがないとはどのようなことを仰っていますか?
3,Nagle アルゴリズムの影響を受けていませんか?
4,Etherealなどで実際にsend時にどのようなパケットが送信されたのか確認はしたのでしょうか?
この回答への補足
ありがとうございます。補足します。
1,ビルド環境はWindowsのVisual C++(をただのCコンパイラとして使っている)です。紙面の都合で書いていませんが、WSAStartupはsocketオープンの前にやってあります。リンク時にwsock32.libも指定しています。実際にHTTP-clientなどは、前述のようにして上手く動いています。
2,4,Ethereal?で確認した訳ではありませんが、
iRC=send(sock,"0\0",2,0);
等として、iRCの返り値が送信量と同じなことを確認しています。
3,すいません。仰っている意味が判りません。
今更何も素人がrshをCでコーディングしなくても...というご意見は大いにあるでしょうが、いろいろ事情(&好み)がありまして...エラーチャック、セキュリティ対策など細かいことは不要です。Linuxサーバ上の(かなり処理時間の掛かる)命令を実行させ、返ってくる結果をバッファで受信・結果判別できれば、目的達成です。
うまくいけば、同じよう記してLinux上でも動かしたいので、できるだけ汎用的な書き方が望ましい野ですが...よろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- デスクトップパソコン 動画編集やフォトショップ、イラストレーターなど、このスペックで問題ないですか? 7 2022/08/19 18:10
- その他(開発・運用・管理) WindowsからSSHでサーバーにあるファイルをダウンロードできない…。 3 2022/04/24 11:08
- その他(プログラミング・Web制作) プログラムの勉強のおすすめは 7 2022/12/09 20:09
- Visual Basic(VBA) VBA★PDFをPDFアプリで印刷しようと思っていますが上手くゆきません 1 2022/06/06 22:04
- その他(パソコン・スマホ・電化製品) LINUXPCに詳しい人に気楽に答えてほしい質問です。 2 2022/10/25 08:07
- 英語 口頭での"the following..."の可否等について 6 2022/08/19 01:01
- C言語・C++・C# exeファイルが作れない(windows10) 6 2022/08/13 08:47
- 日本語 脳科学の奇妙な言語獲得論 2 2022/04/04 13:13
- 労働相談 合意済み仕様の商品納入後における仕様変更要求への対応について 5 2023/04/19 09:41
- 固定電話・IP電話・FAX 業務用ファックスについて 5 2022/09/28 19:08
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語のよるrsh-clientの簡潔...
-
TCP/IP通信時のサーバーからの受信
-
ソケットのクローズについて
-
Winsockで接続待ちタイムアウト...
-
Winsockを使わずにVBでSocketを...
-
UDP通信におけるbind関数について
-
メールサーバへの接続タイムア...
-
ソケットのrecvの戻り値が0
-
WinSockでチャット
-
Socket通信の0バイト受信について
-
WinSockでの通信プログラムがう...
-
Java(クライアント)とC言語(サ...
-
ソケットプログラミングに関す...
-
ポート番号0について
-
WINSOCKのWSACleanupについて
-
UdpClient 送信元のIPアドレ...
-
異なる言語間でのソケット通信...
-
同じLAN内パソコンのIPアドレス...
-
TCP/IP通信型プログラムです。 ...
-
winsockを使った通信での同時接...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
recv関数でフリーズしてしまう
-
Winsockで接続待ちタイムアウト...
-
UDP通信におけるbind関数について
-
エクセル VBA でのCOMポート...
-
Socket通信の0バイト受信について
-
VB6のwinsockでconnectできない
-
ソケットのrecvの戻り値が0
-
ソケットを用いた1対多通信につ...
-
UdpClient 送信元のIPアドレ...
-
ソケットでクライアントのipア...
-
UDP通信する時に、相手にどうや...
-
ソケット通信 同じポート番号...
-
同じLAN内パソコンのIPアドレス...
-
Connectエラーが出てしまう・・...
-
ソケットのクローズについて
-
CreateFile関数でCOMポートが開...
-
異なる言語間でのソケット通信...
-
C言語でHTTP1.1のキープアライ...
-
送信したデータの一部が文字化...
おすすめ情報