使用TCP C#Mutlti线程文件传输 [英] C# Mutlti-threading file transfer using TCP

查看:176
本文介绍了使用TCP C#Mutlti线程文件传输的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我设计的TCP服务器从客户接收文件。其工作一个客户。但是,服务器需要应对多个客户端。我不知道如何在同一时间接收来自客户端的多个文件。请帮我。



服务器代码:

 公共部分Form1类:表
{
线T1;
INT标志= 0;
串receivedPath =郁慕明;
公众委托无效MyDelegate();
私人字符串文件名;
公共Form1中()
{
T1 =新主题(新的ThreadStart(StartListening));
t1.Start();
的InitializeComponent();
}


公共类StateObject
{
//客户端套接字。
公共插座workSocket = NULL;

公共const int的缓冲区大小= 8096;
//接收缓冲区。
公众的byte []缓冲区=新的字节[缓冲区大小]
}

公共静态的ManualResetEvent allDone =新的ManualResetEvent(真);

公共无效StartListening()
{
字节[]字节=新的字节[8096];
IPEndPoint IPEND =新IPEndPoint(IPAddress.Parse(127.0.0.1),9050);
插槽监听器=新的Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

{
listener.Bind(IPEND);
listener.Listen(100);
的setText(监听连接);
,而(真)
{
allDone.Reset();
listener.BeginAccept(新的AsyncCallback(AcceptCallback),监听器);
allDone.WaitOne();

}
}
赶上(异常前)
{
}

}

公共无效AcceptCallback(IAsyncResult的AR)
{
allDone.Set();

插槽监听=(插座)ar.AsyncState;
插槽处理器= listener.EndAccept(AR);

StateObject状态=新StateObject();
state.workSocket =处理程序;
handler.BeginReceive(state.buffer,0,StateObject.BufferSize,0,新的AsyncCallback(ReadCallback),状态);
标志= 0;

}

公共无效ReadCallback(IAsyncResult的AR)
{
INT fileNameLen = 1;
字符串的内容=的String.Empty;
StateObject状态=(StateObject)ar.AsyncState;
插槽处理器= state.workSocket;
INT读取动作= handler.EndReceive(AR);
如果(读取动作大于0)
{
如果(标志== 0)
{
fileNameLen = BitConverter.ToInt32(state.buffer,0);
文件名= Encoding.UTF8.GetString(state.buffer,4,fileNameLen);
receivedPath = @D:\+文件名;
标志++;
}

如果(旗> = 1)
{
的BinaryWriter作家=新的BinaryWriter(File.Open(receivedPath,FileMode.Append));
如果(标志== 1)
{
writer.Write(state.buffer,4 + fileNameLen,读取动作 - (4 + fileNameLen));
标志++;
}
,否则
writer.Write(state.buffer,0,读取动作);
writer.Close();
handler.BeginReceive(state.buffer,0,StateObject.BufferSize,0,新的AsyncCallback(ReadCallback),状态);
}
}
,否则
{
调用(新MyDelegate(LabelWriter));
}

}
公共无效LabelWriter()
{
label1.Text =已接收到数据+文件名;
}

私人无效Form1_FormClosed(对象发件人,FormClosedEventArgs E)
{
t1.Abort();
}


}



客户端代码:

 公共部分Form1类:表格
{
线分路器='\\' ;
串FNAME;
的String []分= NULL;
字节[] clientData;

公共Form1中()
{
的InitializeComponent();
button2.Visible = FALSE;
}

私人无效button1_Click_1(对象发件人,EventArgs五)
{
的char [] =符splitter.ToCharArray();
//openFileDialog1.ShowDialog();
如果(openFileDialog1.ShowDialog()== DialogResult.OK)
{
textBox1.Text = openFileDialog1.FileName;
textBox2.AppendText(选定文件+ textBox1.Text);
button2.Visible = TRUE;
}
,否则
{
textBox2.AppendText(请选择任何一个文件发送);
button2.Visible = FALSE;
}

分割= textBox1.Text.Split(分隔符);
INT极限= split.Length;
FNAME =拆分[极限 - 1]的ToString();
如果(textBox1.Text!= NULL)
button1.Enabled = TRUE;
}

私人无效button2_Click_1(对象发件人,EventArgs五)
{
插槽clientSock =新的Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp) ;
// IP地址IP =新的ip地址;


字节[] =文件名Encoding.UTF8.GetBytes(FNAME); //文件名
字节[] = FILEDATA File.ReadAllBytes(textBox1.Text); //文件
字节[] = fileNameLen BitConverter.GetBytes(fileName.Length); //文件名
clientData的lenght =新的字节[4 + fileName.Length + fileData.Length];

fileNameLen.CopyTo(clientData,0);
fileName.CopyTo(clientData,4);
fileData.CopyTo(clientData,4 + fileName.Length);

textBox2.AppendText(准备发送的文件);
clientSock.Connect(127.0.0.1,9050); //目标机器的IP地址和端口号
clientSock.Send(clientData);
// clientSock。
clientSock.Close();

}


}
}


< DIV CLASS =h2_lin>解决方案

使用异步操作,自然会使用IO线程池,同时运行。只允许接受,并且每个连接状态管理(如接收缓冲区)。



我也建议完全分离工人代码从任何UI代码通信(最服务器将预期无需登录)进行操作。


I am designing TCP server for receiving the file from client. Its working for one client. But Server need to respond multiple clients. I don't know how receive multiple files from clients at a same time. Please help me.

Server Code:

public partial class Form1 : Form
{
    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();
    }


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

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

    public static ManualResetEvent allDone = new ManualResetEvent(true);

    public void StartListening()
    {
        byte[] bytes = new Byte[8096];
        IPEndPoint ipEnd = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);
        Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        try
        {
            listener.Bind(ipEnd);
            listener.Listen(100);
            SetText("Listening For Connection");
            while (true)
            {
                allDone.Reset();
                listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                allDone.WaitOne();

            }
        }
        catch (Exception ex)
        {
        }

    }

    public void AcceptCallback(IAsyncResult ar)
    {
        allDone.Set();

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

        StateObject state = new StateObject();
        state.workSocket = handler;
        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, 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;
        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, 0, new AsyncCallback(ReadCallback), state);
            }
        }
        else
        {
            Invoke(new MyDelegate(LabelWriter));
        }

    }
    public void LabelWriter()
    {
       label1.Text = "Data has been received " + fileName;
    }

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


}

Client Code:

  public partial class Form1 : Form
    {
        string splitter = "'\\'";
        string fName;
        string[] split = null;
        byte[] clientData;

        public Form1()
        {
            InitializeComponent();
            button2.Visible = false;
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            char[] delimiter = splitter.ToCharArray();
            //openFileDialog1.ShowDialog();
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                textBox1.Text = openFileDialog1.FileName;
                textBox2.AppendText("Selected file " + textBox1.Text);
                button2.Visible = true;
            }
            else
            {
                textBox2.AppendText("Please Select any one file to send");
                button2.Visible = false;
            }

            split = textBox1.Text.Split(delimiter);
            int limit = split.Length;
            fName = split[limit - 1].ToString();
            if (textBox1.Text != null)
                button1.Enabled = true;
        }

        private void button2_Click_1(object sender, EventArgs e)
        {
            Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //IPAddress ip = new IPAddress;


            byte[] fileName = Encoding.UTF8.GetBytes(fName); //file name
            byte[] fileData = File.ReadAllBytes(textBox1.Text); //file
            byte[] fileNameLen = BitConverter.GetBytes(fileName.Length); //lenght of file name
            clientData = new byte[4 + fileName.Length + fileData.Length];

            fileNameLen.CopyTo(clientData, 0);
            fileName.CopyTo(clientData, 4);
            fileData.CopyTo(clientData, 4 + fileName.Length);

            textBox2.AppendText("Preparing File To Send");
            clientSock.Connect("127.0.0.1", 9050); //target machine's ip address and the port number
            clientSock.Send(clientData);
            //clientSock.
            clientSock.Close();

        }


    }
}

解决方案

Using asynchronous operations will naturally use the IO thread pool and operate concurrently. Just allow accept and have per-connection state management (eg. receive buffers).

I would also suggest completely separating the worker code for the communications from any UI code (most servers would be expected to operate without requiring a logon).

这篇关于使用TCP C#Mutlti线程文件传输的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆