发送和接收文件套接字编程

时间:2010-07-28 14:40:02

标签: c# sockets

我正在开发两个应用程序,一个是服务器应用程序,另一个是用于手持设备 应用程序都使用无线连接进行通信。客户端是手持设备,服务器是 运行服务器应用程序的计算机。当我从客户端发送文件到服务器时,它发送 完美没有任何错误,但当客户端请求文件服务器产生错误 就像是  “无法建立连接,因为目标机器主动拒绝它192.168.1.5:9050”

服务器端代码:

    private bool SendData(string StrIP)
    {

        try
        {
            string strmyFile = Directory.GetCurrentDirectory() + "\\" + "XML" + @"\Login.xml";
            char[] delimiter = splitter.ToCharArray();
            split = strmyFile.Split(delimiter);
            int limit = split.Length;
            fName = split[limit - 1].ToString();

            byte[] fileName = Encoding.UTF8.GetBytes(fName); //file name
            byte[] fileData = File.ReadAllBytes(strmyFile); //file
            using (FileStream stream = File.OpenRead(strmyFile))
            {
                fileData = new byte[stream.Length];
                stream.Read(fileData, 0, fileData.Length);
            }

            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);

            System.Net.IPAddress ipAdd = System.Net.IPAddress.Parse(StrIP);

            try
            {
                Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint ipEnd = new IPEndPoint(ipAdd, 9050);
                clientSock.Connect(ipEnd); //target machine's ip address and the port number
                clientSock.Send(clientData);
                clientSock.Close();
                ind = 1;

                //Socket Sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //IPEndPoint ipEnd = new IPEndPoint(ipAdd, 9050);
                //Sock.Bind(ipEnd);//target machine's ip address and the port number
                //Sock.Listen(100);

                //Socket clientSock = Sock.Accept();

                //clientSock.Send(clientData);
                //clientSock.Close();
                //ind = 1;
            }
            catch (Exception ex)
            {

                req = false;
                return false;

            }
            req = true;
        }
        catch (Exception ex)
        {

        }
        return true;
    }


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

        public const int BufferSize = 1024 * 5000;
        // Receive buffer.
        public byte[] buffer = new byte[BufferSize];
    }

    public static ManualResetEvent allDone = new ManualResetEvent(false);

    public void StartListening()
    {


        byte[] bytes = new Byte[1024 * 5000];
        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();
               // string ip = listener.RemoteEndPoint.ToString();
                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;

    }

    private bool req = false;
    public void ReadCallback(IAsyncResult ar)
    {
        try
        {

            int fileNameLen = 1;
            String content = String.Empty;
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.workSocket;
            string[] str = new string[2];
            str = handler.RemoteEndPoint.ToString().Split(':');
            string path = Directory.GetCurrentDirectory() + "\\TEST\\" + str[0].ToString();
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            if (req == false)
            {
                Sender snddata = new Sender();
                snddata.sendme(str[0].ToString());
                SendData(str[0].ToString());
            }

            int bytesRead = handler.EndReceive(ar);

            if (bytesRead > 0)
            {
                    if (flag == 0)
                    {
                        fileNameLen = BitConverter.ToInt32(state.buffer, 0);
                        string fileName = Encoding.UTF8.GetString(state.buffer, 4, fileNameLen);
                        receivedPath = Directory.GetCurrentDirectory() + "\\TEST\\" + str[0].ToString() + @"\" + 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));
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);

        }
    }
public class Sender
{
    public void sendme(string strIP)
    {
        try
        {
           // MessageBox.Show("That program can transfer small file. I've test up to 850kb file");
            IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 9050);
            Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
            sock.Bind(ipEnd);
            sock.Listen(100);

            while (true)
            {
                //clientSock is the socket object of client, so we can use it now to transfer data to client
                Socket clientSock = sock.Accept();


                string fileName =  "Login.xml";// "Your File Name";
                string filePath = Directory.GetCurrentDirectory() + "\\" + "XML" + @"\" ;//Your File Path;
                byte[] fileNameByte = Encoding.ASCII.GetBytes(fileName);

                byte[] fileData = File.ReadAllBytes(filePath + fileName);
                byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
                byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);

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


                clientSock.Send(clientData);
               //MessageBox.Show("File:{0} has been sent." + fileName);
            }
            //sock.Shutdown(SocketShutdown.Both);
            //sock.Close();


           // Console.ReadLine();
            //sendme();
        }
        catch (Exception ex)
        {
            MessageBox.Show("File Receiving fail." + ex.Message);
        }
    }
}

客户端代码:

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

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

    public static ManualResetEvent allDone = new ManualResetEvent(false);

    public void StartListening()
    {
        byte[] bytes = new Byte[1024];
        IPAddress address = IPAddress.Parse(ServerIP);
        IPEndPoint ipEnd = new IPEndPoint(address, 9050);
        Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        try
        {
            listener.Bind(ipEnd);
            listener.Listen(100);

            while (true)
            {
                allDone.Reset();
                // string ip = listener.RemoteEndPoint.ToString();
                listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                allDone.WaitOne();

            }
        }
        catch (Exception ex)
        {
            throw 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)
    {

        try
        {

            int fileNameLen = 1;
            String content = String.Empty;
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.workSocket;
            //string[] str = new string[2];
            //str = handler.RemoteEndPoint.ToString().Split(':');
            string path = mypath + "@Login.XML";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            int bytesRead = handler.EndReceive(ar);

            if (bytesRead > 0)
            {

                if (flag == 0)
                {
                    fileNameLen = BitConverter.ToInt32(state.buffer, 0);
                    string fileName = Encoding.UTF8.GetString(state.buffer, 4, fileNameLen);
                    receivedPath = mypath + "@Login.XML";
                    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));
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);

        }
    }
    public void LabelWriter()
    {
       MessageBox.Show("Data has been received");
       Programs p = new Programs();
       p.GetFile(serverIP);
    }

此代码用于从服务器获取文件。

private void GetLoginTemp()
    {
        Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        try
        {
            char[] delimiter = splitter.ToCharArray();
            byte[] fileName = Encoding.UTF8.GetBytes("empty"); //file name
            byte[] fileData;
            fileData = Encoding.UTF8.GetBytes("empty");
            //byte[] fileData = reads.ReadToEnd().to; //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);
            System.Net.IPAddress ipAdd = System.Net.IPAddress.Parse(serverIP);

            IPEndPoint ipEnd = new IPEndPoint(ipAdd, 9050);
            clientSock.Connect(ipEnd); //target machine's ip address and the port number
            clientSock.Send(clientData);

            byte[] clientData1 = new byte[1024 * 5000];
            string receivedPath = mypath + @"\XML" + @"\Login.xml";

            int receivedBytesLen = clientSock.Receive(clientData1);

            int fileNameLen1 = BitConverter.ToInt32(clientData1, 0);
            string fileName1 = Encoding.ASCII.GetString(clientData1, 4, fileNameLen1);

            BinaryWriter bWrite = new BinaryWriter(File.Open(receivedPath + fileName, FileMode.Append)); ;
            bWrite.Write(clientData, 4 + fileNameLen1, receivedBytesLen - 4 - fileNameLen1);
            //clientSock.Shutdown(SocketShutdown.Send);

            clientSock.Close();
        }
        catch (Exception ex)
        {
            clientSock.Close();
            MessageBox.Show(ex.Message);
        }
    }

4 个答案:

答案 0 :(得分:8)

您似乎认为在文件传输方向上需要第二个TCP连接。这不是必需的,因为TCP连接是全双工流。此外,从服务器返回到客户端也不是一个好的设计,这可能是NAT-ing网关/防火墙的背后。这是FTP的问题(见active vs passive ftp)。

使用客户端已建立的相同连接。您需要在基础TCP之上使用某种协议,让对方知道何时需要数据以及预期的数量。这已经在这里讨论了很多次,例如参见this SO question

答案 1 :(得分:0)

仅从您收到的错误(我多次出现相同的错误)检查您用于通信的基础流是否未关闭,或者您是否尝试重新使用已关闭的流

您是否有发生错误的特定行?

答案 2 :(得分:0)

您可能需要检查系统防火墙以确保允许连接。使用ping和telnet非常适合调试。

答案 3 :(得分:0)

如果它不是防火墙,我认为让服务器监听(启动服务器)就这么简单

我建议这段代码可以解决您的问题:

var prg = StateObject();
prg.StartListening;

在您管理完之后,请告诉我是否已发送超过8KB的文件