1

C# サーバーから AS3 Flash クライアントにファイルを送信したいと考えています。ファイルを送信するための私の C# サーバー コードは次のようなものです。

IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 5656);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
sock.Bind(ipEnd);
sock.Listen(100);
//clientSock is the socket object of client, so we can use it now to transfer data to client
Socket clientSock = sock.Accept();

// This part gets the file and send the data in bytearray
byte[] fileData = File.ReadAllBytes("send/mypicture.jpg");
clientSock.Send(fileData);

今、私は as3 クライアントが必要です。私はこれを見つけました: http://flasharp.blogspot.pt/2010/03/socket-serverclient-chat.htmlそして私はこのようなものを構築しました:

public function Main():void {
    ...
    socket.addEventListener(ProgressEvent.SOCKET_DATA, onResponse);
    ...
}

function onResponse(e:ProgressEvent):void {
    var file:File;
    var fs:FileStream;
    var fileData:ByteArray = new ByteArray();

    // Check if socket has data
    if(socket.bytesAvailable > 0) {
        while(socket.bytesAvailable) {
            // read the socket data into the fileData
            socket.readBytes(fileData,0,0);
        }
    }
    file = File.documentsDirectory.resolvePath("teste.jpg");
    fs = new FileStream();
    fs.open(file, FileMode.WRITE);
    // Writing the file
    fs.writeBytes(fileData);
    fs.close();
}

私はなんとかファイルを送受信しましたが、保存できるのは最大 50kbs までで、それ以上のサイズのファイルを取得するだけです。

任意のサイズのファイルを転送する方法について何か考えはありますか?

4

1 に答える 1

1

私はなんとかこれを解決し、この投稿をサンプルで更新しました。

更新および解決済み: ローカル ネットワークのソケットを使用して、C# サーバーから AS3 クライアントにファイルを送信したいと考えていました。やり方がわからなくて苦労しましたが、なんとかできました。

サーバー (C#):
1 -TcpListener指定されたポート番号に対して、そのネットワーク内の任意の IP を持つ新しいクライアントをリッスンする を作成します。
2 - 新しいクライアントが接続すると、Threadそれを処理するために を作成します。
3 - その中でThread、必要なデータを送信します。この場合、データは 2 つの部分に分割されます。1 つbytearray目は送信するファイルのサイズを含む 4 で、2 つ目はbytearrayファイル自体の です。
4 - データが送信されたら、そのクライアント接続を閉じます。

クライアント (AS3):
1 - まず最初に を に変換bytearraysします。LITTLE_ENDIANデフォルトBIG_ENDIANでは AIR であり、サーバーから取得したデータはLITTLE_ENDIAN;であるためです。
2 - イベントをソケット接続に追加し、サーバーに接続します。
3 -onResponse関数で、ソケット パッケージをbytearray;に受け取ります。
4 - ファイルに保存しbytearrayます。

BIG_ENDIANクライアントの最後の部分は、AIR がデフォルトであることと、パッケージの読み方を理解するのに時間がかかったので、最も厄介な部分でした。つまり、基本的には、入ってきた最初のパッケージで、最初の 4 バイトを に読み取り、bytearrayそれを に変換することでint、合計ファイル サイズがわかります。これを使用して、受信するパッケージがなくなったことを認識し、接続を終了してファイルを保存します。最初のパッケージの残りと後続のパッケージは、bytearrayそのファイルデータ自体を保存します。ここでの回避策は、最初にパッケージを受け取ったときに最初から書き込みを開始し、最後のパッケージが中断された場所に後続のパッケージを追加することです。 65321 から XXXX など。

ファイルは MyDocuments フォルダーに保存されています。

私はソケット接続にかなり慣れていないので、これがこれを行うための最良の方法であるかどうかはわかりませんが、これは私にとってはうまくいき、最大165MBのファイルでテストしましたが、うまくいきました。複数のクライアント接続をサポートし、非常に基本的ですが、これはゴールではなくスタート地点です。

ウェブ上でそのようなものを見つけられなかったので(C#ではなくファイル転送に関して-> AS3接続)、これが私を助けてくれたので、他の人を助けることができることを願っています。

誰かが情報を入力したい場合、または何かについて明確にする必要がある場合は、お気軽にお問い合わせください。

最後になりましたが、サンプルはhttp://sdrv.ms/W5mSs9からダウンロードできます(C# Express 2010 のサーバーと Flex SDK 4.6.0 を使用した Flash Builder 4.6 のクライアント)。

上記のリンクのサンプルがこれまでになくなった場合は、ここにあります

ActionScript 3 ソース コード:

package
{
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent;
    import flash.events.SecurityErrorEvent;
    import flash.filesystem.File;
    import flash.filesystem.FileMode;
    import flash.filesystem.FileStream;
    import flash.net.Socket;
    import flash.system.Security;
    import flash.utils.ByteArray;
    import flash.utils.Endian;
    import flash.text.TextField;

    public class FileTransferLocal extends Sprite
    {
        private var socket:Socket = new Socket();
        private var file:File;
        private var fs:FileStream = new FileStream();
        private var fileData:ByteArray = new ByteArray();
        private var fileSize:ByteArray = new ByteArray();

        private var fileDataPosition:int = new int();
        private var fileDataFlag:int = new int();
        private var fileSizeFlag:int = new int();
        private var fileSizeCounter:int = new int();

        private var fileDataPreviousPosition:int = new int();

        private var myText:TextField = new TextField();


        public function FileTransferLocal()
        {           
            try {Security.allowDomain("*");}catch (e) { };

            // Convert bytearray to Little Endian
            fileSize.endian = Endian.LITTLE_ENDIAN;
            fileData.endian = Endian.LITTLE_ENDIAN;
            socket.endian = Endian.LITTLE_ENDIAN;

            fileSizeFlag = 0;
            fileDataFlag = 0;

            myText.width = 150;
            myText.height = 150;
            myText.x = 200;
            myText.y = 200;

            socket.addEventListener(Event.CONNECT, onConnect);
            socket.addEventListener(Event.CLOSE, onClose);
            socket.addEventListener(IOErrorEvent.IO_ERROR, onError);
            socket.addEventListener(ProgressEvent.SOCKET_DATA, onResponse);
            socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecError);

            // Put the IP and port of the server
            socket.connect("10.1.1.211", 5656);
        }

        private function onConnect(e:Event):void {
            trace("onConnect\n");
        }

        private function onClose(e:Event):void {
            trace("onClose");
            socket.close();
        }

        private function onError(e:IOErrorEvent):void {
            trace("IO Error: "+e);
        }

        private function onSecError(e:SecurityErrorEvent):void {
            trace("Security Error: "+e);
        }

        private function onResponse(e:ProgressEvent):void {         

            if(!fileSizeFlag) {
                socket.readBytes(fileSize, 0, 4);
                fileSize.position = 0;
                fileSizeFlag = 1;
                fileSizeCounter = fileSize.readInt();
                trace("fileSizeCounter -> " + fileSizeCounter);
            }

            trace("---- New package ----> " + socket.bytesAvailable);

            if(fileSizeCounter > 0) {
                fileSizeCounter -= socket.bytesAvailable;

                if(fileDataPosition != 0) {
                    fileDataPreviousPosition += fileDataPosition;
                }

                if(fileData.length == 0) {
                    fileDataPreviousPosition = socket.bytesAvailable;
                    socket.readBytes(fileData, 0, socket.bytesAvailable);
                } else {
                    fileDataPosition = socket.bytesAvailable;
                    socket.readBytes(fileData, fileDataPreviousPosition, socket.bytesAvailable);
                }
            }

            // Saves the file
            if(fileSizeCounter == 0) {
                trace("File total size" + fileData.length);
                file = File.documentsDirectory.resolvePath("test.mp3");
                fs.open(file, FileMode.WRITE);
                fs.writeBytes(fileData);
                fs.close();

                myText.text = "File successefully\nreceived!";
                addChild(myText);

            }
            // Is still receiving packages
            else {
                myText.text = "Receiving file...";
                addChild(myText);
            }

        }
    }
}

C# で新しい Windows アプリケーションを作成し
、ListBox を追加し
ます。statusList
ラベルを呼び出します。port ラベルを呼び出し
ます。

上記のサンプルの C# ソース コード:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.IO;
using System.Reflection;

namespace ServerThread
{
    public partial class ServerThread : Form
    {
        private TcpListener tcpListener;
        private Thread listenThread;

        public ServerThread()
        {
            InitializeComponent();

            // Port number
            int portNumber = 5656;
            port.Text = portNumber.ToString();

            // Create a TcpListener to cover all existent IP addresses with that port
            this.tcpListener = new TcpListener(IPAddress.Any, portNumber);
            // Create a Thread to listen to clients
            this.listenThread = new Thread(new ThreadStart(ListenForClients));
            this.listenThread.Start();

        }

        private void ListenForClients()
        {
            this.tcpListener.Start();

            while (true)
            {
                // Blocks until a client has conected to the server
                TcpClient client = this.tcpListener.AcceptTcpClient();

                // Create a Thread to handle the conected client communication
                Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
                clientThread.Start(client);
            }
        }

        private void HandleClientComm(object client)
        {
            // Receive data
            TcpClient tcpClient = (TcpClient)client;
            NetworkStream clientStream = tcpClient.GetStream();

            while (true)
            {
                try
                {
                    // Sending data
                    string filePath = "send/mysong.mp3"; // Your File Path;
                    byte[] fileData = File.ReadAllBytes(filePath); // The size of your file
                    byte[] fileSize = BitConverter.GetBytes(fileData.Length); // The size of yout file converted to a 4 byte array
                    byte[] clientData = new byte[fileSize.Length + fileData.Length]; // The total byte size of the data to be sent

                    fileSize.CopyTo(clientData, 0); // Copy to the file size byte array to the sending array (clientData) beginning the in the 0 index
                    fileData.CopyTo(clientData, 4); // Copy to the file data byte array to the sending array (clientData) beginning the in the 4 index

                    // Send the data to the client
                    clientStream.Write(clientData, 0, clientData.Length);
                    clientStream.Flush();


                    // Debug for the ListBox
                    if (statusList.InvokeRequired)
                    {
                        statusList.Invoke(new MethodInvoker(delegate {
                            statusList.Items.Add("Client IP: " + tcpClient.Client.RemoteEndPoint.ToString());
                            statusList.Items.Add("Client Data size: " + clientData.Length);
                        }));
                    }

                }
                catch
                {
                    // 
                    break;
                }

                if (statusList.InvokeRequired)
                {
                    statusList.Invoke(new MethodInvoker(delegate
                    {
                        statusList.Items.Add("File successefully sent!");
                    }));
                }

                // Close the client
                tcpClient.Close();
            }

        }
    }
}
于 2012-12-13T11:00:41.200 に答える