如何使用C#一次通过TCP连接从多个客户端接收文件?

时间:2012-02-27 06:24:08

标签: c# sockets tcp

我的项目中有一台服务器和多个客户端。服务器需要按请求发送文件,并存储来自客户端的文件。我有编码,连接多个客户端但是一次收到一个文件。其他文件存储请求将在完全收到上一个文件后继续。

我的文件大小约为200 MB。所以回复所有客户需要更多时间。我将如何解决这个问题。任何人都帮助我。提前致谢。

public partial class Form1 : Form
{
    byte[] Echo;
    byte[] a;
    Thread t1;
    int flag = 0;
    string receivedPath = "yok";
    public delegate void MyDelegate();
    private string fileName;
    public Form1()
    {
        t1 = new Thread(new ThreadStart(StartListening));
        t1.Start();
        InitializeComponent();
    }

    delegate void SetTextCallback(string text);

    public class StateObject
    {
        // Client socket.
        public Socket workSocket = null;

        public const int BufferSize = 8069;
        // Receive buffer.
        public byte[] buffer = new byte[BufferSize];
    }

    public static ManualResetEvent allDone = new ManualResetEvent(true);

    public void StartListening()
    {

        StateObject state = new StateObject();
        byte[] bytes = new Byte[8069];
        IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 9050);
        Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        try
        {
            listener.Bind(ipEnd);
            listener.Listen(100);
            while (true)
            {
                allDone.Reset();
                listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                allDone.WaitOne();

            }
        }
        catch (Exception ex)
        {
            SetText(ex.ToString());
        }

    }

    public void AcceptCallback(IAsyncResult ar)
    {

        Socket listener = (Socket)ar.AsyncState;
        Socket handler = listener.EndAccept(ar);

        StateObject state = new StateObject();
        state.workSocket = handler;
        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, SocketFlags.None, new AsyncCallback(ReadCallback), state);
        flag = 0;


    }

    public void ReadCallback(IAsyncResult ar)
    {
        int fileNameLen = 1;
        String content = String.Empty;
        StateObject state = (StateObject)ar.AsyncState;
        Socket handler = state.workSocket;
        try
        {
            int bytesRead = handler.EndReceive(ar);
            if (bytesRead > 0)
            {

                if (flag == 0)
                {

                    fileNameLen = BitConverter.ToInt32(state.buffer, 0);
                    fileName = Encoding.UTF8.GetString(state.buffer, 4, fileNameLen);
                    receivedPath = @"D:\" + fileName;
                    flag++;

                }

                if (flag >= 1)
                {
                    BinaryWriter writer = new BinaryWriter(File.Open(receivedPath, FileMode.Append));
                    if (flag == 1)
                    {
                        writer.Write(state.buffer, 4 + fileNameLen, bytesRead - (4 + fileNameLen));
                        flag++;
                    }
                    else
                    writer.Write(state.buffer, 0, bytesRead);
                    writer.Close();
                    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, SocketFlags.None, new AsyncCallback(ReadCallback), state);
                }
            }
            else
            {

                allDone.Set();
                Invoke(new MyDelegate(LabelWriter));
            }
        }
       catch
        {
        }
    }
    public void LabelWriter()
    {
        label1.Text = "Data has been received " + fileName;
    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        t1.Abort();
    }


}

1 个答案:

答案 0 :(得分:0)

您可以在AcceptCallback方法中触发allDone事件。在接受客户端后,您可以自动启动与该客户端通信的进程,同时开始侦听下一个客户端。