インターネット(またはLAN)を介してC ++を使用して、あるコンピューターから別のコンピューターに基本的なテキストファイルを送信するプログラムを作成しようとしています。Winsockを調べていましたが、読んだものはすべて、サーバーとクライアント間の通信専用のように見えました。これが私がやろうとしていることなのか、それとも別の問題を見ているのかはわかりません。
編集:素晴らしい答えをありがとう。たくさんの中から最高のものを選ばなければならないのはちょっと気分が悪いです。
インターネット(またはLAN)を介してC ++を使用して、あるコンピューターから別のコンピューターに基本的なテキストファイルを送信するプログラムを作成しようとしています。Winsockを調べていましたが、読んだものはすべて、サーバーとクライアント間の通信専用のように見えました。これが私がやろうとしていることなのか、それとも別の問題を見ているのかはわかりません。
編集:素晴らしい答えをありがとう。たくさんの中から最高のものを選ばなければならないのはちょっと気分が悪いです。
LinuxでC/C++を使用してファイルをコピー/転送する方法の例を次に示します。server
ポート8080でリッスンしclient
ます。はファイル名を送信します。はserver
ファイル名を受け取り、ファイルを開いてその内容をクライアントに送信します。説明のために、意図的に奇数または小さいバッファーサイズを使用しました。
server.c
ファイル:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>
int main (int argc,char *argv[])
{
struct sockaddr_in p;
struct sockaddr_in q;
int z,s,t,x,n,b = sizeof(q);
char buf[23];
int fd;
s = socket(AF_INET,SOCK_STREAM,0);
bzero (&p,sizeof(p));
p.sin_family = AF_INET;
p.sin_addr.s_addr = INADDR_ANY;
p.sin_port = htons(8080);
bind (s,(struct sockaddr*)&p,sizeof(p));
listen(s,13);
while (1) {
t = accept (s,(struct sockaddr*)&q, &b);
n = read(t,buf,23);
buf[n] = 0;
printf("%s sent: ",buf);
fd = open (buf,O_RDONLY);
z = lseek(fd,0,SEEK_END);
lseek(fd,0,SEEK_SET);
x = 0;
do {
n = read (fd,buf,23);
write (t,buf,n);
x += n;
} while (x < z);
printf("%d/%d\n",x,z);
close(fd);
close(t);
}
}
client.c
ファイル:
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
void main (int argc, char *argv[])
{
int ret;
char buf[5];
int s,n,fd;
struct sockaddr_in p;
struct hostent *h;
char *str = argv[1];
fd = open (str,O_CREAT | O_WRONLY,S_IRUSR|S_IWUSR);
h = gethostbyname("127.0.0.1");
bzero(&p,sizeof(p));
p.sin_family = AF_INET;
p.sin_addr.s_addr = htonl(INADDR_ANY);
p.sin_addr.s_addr = ((struct in_addr*)(h->h_addr))->s_addr;
p.sin_port = htons(8080);
s = socket (AF_INET,SOCK_STREAM,0);
connect (s,(void*)&p,sizeof(p));
n = write (s,str,strlen(str));
int idx = 0;
do {
n = read (s,buf,5);
idx += n;
printf(".");
fflush(stdout);
write (fd,buf,n);
} while (n > 0);
close (fd);
close (s);
}
コンパイルする:
サーバーをとして実行します./server
。次に、コピーrngoidiot.txt
するには、クライアントをとして実行する./client rngoidiot.txt
と、ファイルはTCP/IPを使用してコピーされます。簡単な組み合わせ;-)
ファイルの送信には、クライアントサーバーアーキテクチャで十分です。「サーバー」とは、最初に起動し、他のサーバー(クライアント)が接続するのを待つプログラムのことです。そこを過ぎると、2つの間に大きな違いはありません。多くの場合、コードを記述してサーバーへの接続を自動的に試行し、サーバーが見つからない場合はサーバーとして設定するのが最も簡単です。
また、(特に)NATルーターを使用してインターネット上で動作させると、コードが少し複雑になる可能性があることにも注意してください。接続を許可するようにファイアウォールを事前構成する場合はそれほど難しいことではありませんが、そうでない場合は通常、UPnPを使用してファイアウォールを介した接続を確立することになります。これにより、NATを使用せずにローカルでジョブを実行する場合と比較して、作業が簡単に2倍になります。
要するに:はい、ソケットは行く方法です。
ソケットの意味での「サーバー」と「クライアント」は一般的な用語です。システムは常にさまざまな両方を実行しています。たとえば、WebブラウザはHTTPクライアントとして動作します(HTTPは、TCP / IP上で実行されるテキスト境界のほぼ同期プロトコルです)。Windowsファイル共有とリモートデスクトップは、他のシステムが接続する「サーバー」です。
ソケットの意味(実際にはTCP / IPの意味)でのサーバーとクライアントの違いは、「サーバー」ソケットがリモートシステムからの着信接続をリッスンすることです(MSDNまたはbind()、listen()、acceptのマニュアルページを参照) ())一方、「クライアント」ソケットはリモートシステムへの発信接続を作成します(connect())。
ソケットプログラミングは少し注意が必要です。あなたが説明することは良い学習演習ですが、何かを素早く成し遂げようとしているなら、netcatのような既存のツールを見るかもしれません。
サーバーとクライアント間の通信専用だったようです
だから何?1台のコンピューター(ファイルを受信しようとしている)をサーバーにします。そのコンピューターでソケットを作成し、ポートでの接続をリッスンするようにします。接続が到着したら、定義された構造に従ってデータを取得します(以下を参照)
送信側のコンピューター(クライアント、一種)は他のコンピューターに接続し、IPアドレスとポート番号を認識します。(この2つは、接続のためにクライアントに認識されている必要があります)。接続が確立されると、データが一連のバイトとしてサーバーに送信されます。
構造:
ここで通信している2台のコンピューターは、両方に認識され、受け入れられている明確に定義された構造を持っている必要があります。最も単純な構造は次のとおりです。
|Length-Of-Data | Data ...... |
<-- 4 bytes---> <-- n bytes-->
n
最初の4バイトからを読み取ります。ここでの4
バイト(n
)はデータの長さを表し、定義によって異なる場合があります。
ファイル名、ファイルタイプなどのために(機能に応じて)さらに多くの「フィールド」を持つことができます。
インターネット経由でファイルを送信する場合は、ソケットを使用する必要があります。さらに、ソケットを使用して実装された他の高レベルのライブラリを使用する必要があります。
TCPソケットの用語では、クライアントとサーバーの間に大きな違いはありません。通信は双方向です。唯一の違いは、着信接続をリッスンしているユーザー(バインド、リッスン、受け入れ)と、接続を開始しているユーザー(オープン)です。
Winsockについておっしゃいましたが、これはWindowsで作業していることを意味します。Windows APIを調べてみてください。おそらく、ファイル転送を処理する高レベルのライブラリ(FTPやHTTPライブラリなど)を見つけることができます。
要件に合わないかもしれませんが、LAN用の共有フォルダーとインターネット用のDropboxによって同期されたフォルダーを使用することもできます...その後、標準のIOを使用します。
一般的に言えば、ファイル転送には何らかのサーバー/クライアント接続が必要です。一方のコンピューターは接続を開始する必要があり、もう一方のコンピューターはもう一方の端で接続をリッスンしてから、最初のコンピューターから指示されたアクションを実行する必要があります。
ソケットを使用して独自のクライアントおよびサーバーソフトウェアを展開することはできますが、ファイルを転送するコンピューターの種類によっては、既存のクライアント/サーバープロトコルを利用するのが最も理にかなっている場合があります。より一般的な可能性には、ssh、http、またはftpが含まれます。これらすべてのプロトコルにC/C++ライブラリが存在する必要があると思います。
これ以上の情報がなければ、sshを使用する傾向があります。sshサーバーのインストールはそれほど難しくないはずなので、クライアントソフトウェアを作成するだけで済みます。そのために、かなり優れたオープンソースライブラリがいくつか存在すると思います。
編集:libsshはかなりよさそうだ!