- ベストアンサー
winsockでファイル転送
教えてください。 windockを使いファイルをサーバ側からクライアント側に転送したいのですが、テキストファイルfgetsで一行ずつ読み込んで、それをsendで転送し、クライアントでrecvで読み取り、テキストファイルに書き出す。 という一連の流れより、もっと簡単に、ファイルを転送する方法又はMFCの関数等ありますか? [環境] visual C++ 6.0 MFC
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
実際送信するときはキャストしないとまずいですね send(sock, (char*)&header, sizeof(header), 0); 何で大丈夫かというのはC++の理解度が高まったときにわかると思います ただし構造体の中身がポインターやクラスだとうまくいきません うまく送れるのは固定長のデータだけです 構造体のメモリを確保したときにどんな感じで確保されるかを理解できれば問題ないかと・・ さすがにそこら辺の詳しい解説はうまくできないのと最初の質問とかけ離れてしまうのがあるのでここでは控えさせていただきます
その他の回答 (2)
- nobunaga_oda
- ベストアンサー率72% (8/11)
そのような流れでいいと思います プログラム的には次のようになると思います // 送信側 ------------------------------- char header[256] = {0}; sprintf(header, "%d", nFileSize); send(sock, header, sizeof(header), 0); send(sock, pFileBuffer, nFileSize);, 0); // 受信側 ------------------------------- char header[256] = {0}; recv(sock, header, sizeof(header), 0); int nFileSize = atoi(header); char *pFileBuffer = new char[nFileSize]; recv(sock, pFileBuffer, nFileSize, 0); ヘッダー自体はchar型でなくても問題ないです 構造体を作って送ってしまった方が楽かも知れません typedef struct tag_MyHeader { int nBufferSize; char fileName[_MAX_FNAME+1]; // などなど } MYHEADER; などとしておき、 // 送信側 ------------------------------- MYHEADER header = {0}; header.nBufferSize = nFileSize; strcpy(header.fileName, "abc.txt"); send(sock, header, sizeof(header), 0); send(sock, pFileBuffer, header.nBufferSize);, 0); // 受信側 ------------------------------- MYHEADER header = {0}; recv(sock, header, sizeof(header), 0); char *pFileBuffer = new char[header.nBufferSize]; recv(sock, pFileBuffer, header.nBufferSize, 0); printf("File [%s]を受信しました\n", header.fileName); みたいにすれば問題ないと思います
お礼
しつもんです。 構造体ってconst Char *でSendって出来るのでしょうか?
- nobunaga_oda
- ベストアンサー率72% (8/11)
MFC + socketならば CSocketクラスかな? -- ヘルプより抜粋 -- CSocket クラスは、CAsyncSocket クラスから派生し、Windows ソケット API のカプセル化を継承しています。 CSocket オブジェクトは、CAsyncSocket オブジェクトよりも高いレベルで Windows ソケット API の抽象化を表現しています。 CSocket は、CSocketFile と CArchive を組み合わせて動作し、データの送受信を管理します。 -- ヘルプより抜粋 -- なので、CSocket CSocketFile CArchive あたりを調べるといいかも * 当方使い方は知りません 状況がわからないので簡単にネットワーク越しのPCにファイルを転送となると 1.ネットワークドライブを割り当ててファイルコピーを行う 2.自分独自のヘッダを付加し、転送する たとえば256バイトのヘッダ情報をつける 送信側はヘッダ情報にファイルサイズを書いておく 送信側はまずヘッダ情報を送信する(256バイト) 続いてファイルの中身を転送する(ファイルサイズ) 受信側は最初にヘッダ情報のみを受信する(256バイト) ヘッダ情報に従って残りのデータを受信する(ファイルサイズ) 上記2の方法だと色々応用が利くので個人的には好きです
補足
ご返答ありがとうございます。 >1.ネットワークドライブを割り当ててファイルコピーを行う。 これは考えていたのですが、いろいろ問題がありましたので、却下いたしました。 CSocketはこれから調べてみます。 > 2.自分独自のヘッダを付加し、転送する イメージがわかないため、ご質問あります。 1. ヘッダー情報を作成する。例えば)sendコマンド等で"HD =ファイルサイズ" 2. その後、受信側で変数(recvのバッファーサイズに該当する?)にファイルサイズをを挿入 3. 送信側のファイルの中身を転送 4. 受信側でファイルを受信 という流れになるのでしょうか? お聞きしてしまって申し訳ありませんが、よろしくお願いします。
お礼
ありがとうございました。 >うまく送れるのは固定長のデータだけです なるほど。 >構造体のメモリを確保したときにどんな感じで確保されるかを理解できれば問題ないかと・・ 少し理解しました。 >さすがにそこら辺の詳しい解説はうまくできないのと最初の質問とかけ離れてしまうのがあるのでここでは控えさせていただきます 確かにその通りです。