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我发送我想要的数据。在这种情况下,数据分为两部分,第一部分是bytearray包含我要发送的文件大小的 4,第二部分是bytearray文件本身的大小;
4 - 发送数据后,我关闭该客户端连接;

客户端 (AS3):
1 - 首先我将我的转换bytearraysLITTLE_ENDIANAIR,因为默认情况下是 AIR,BIG_ENDIAN而我从服务器获取的数据是LITTLE_ENDIAN
2 - 将事件添加到套接字连接并连接到服务器;
3 - 在onResponse我收到套接字包的功能上bytearray;
4 - 将其保存bytearray到文件中;

客户端的最后一部分是最棘手的部分,因为我花了一些时间才弄清楚 AIR 是BIG_ENDIAN默认的,以及如何读取包。所以基本上,我所做的是,在进来的第一个包中,我将前 4 个字节读取为 a bytearray,然后将其转换为 a int,这给出了我的总文件大小。我用它来知道什么时候没有更多的包要接收,从而完成连接并保存文件。第一个包的其余部分和后续包被添加到一个bytearray这将存储该文件数据本身。这里的解决方法是在第一次收到包裹时开始写,然后在最后一个停止的地方添加后续的包裹,即第一次我从 0 写到 65321,第二个我必须写从 65321 到 XXXX,以此类推。

该文件正在保存到 MyDocuments 文件夹。

我不确定这是否是最好的方法,因为我对套接字连接相当陌生,但是这对我有用,并且我用高达 165MB 的文件进行了测试并且它可以工作。它支持多个客户端连接并且非常基本,但这是一个起点,而不是终点。

我希望这可以帮助其他人,因为它帮助了我,因为我没有在网上找到类似的东西(关于文件传输而不是 C# -> AS3 连接)。

如果有人想输入一些信息或需要澄清某些事情,请随时询问。

最后但同样重要的是,可以在此处下载示例:http: //sdrv.ms/W5mSs9(C# Express 2010 中的服务器和带有 Flex SDK 4.6.0 的 Flash Builder 4.6 中的客户端)

如果上面链接中的示例在这里消失了,那就是

动作脚本 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
标签调用它端口
标签调用它状态

上面示例中的 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 回答