问题一:
看csdn里面,TCP网络的发送可以用 socket.send()方法,也可以将socket先流化,即NetworkStream ns=new NetworkStream(socket),再调用ns.write()进行发送。请问这两种发送方法有什么区别么?问题二:
socket.send()出去后,再另一端可以将接听的socket流化,再调用ns.wread()进行读么?谢谢大家了!!

解决方案 »

  1.   

    转贴:如果想要利用C#通过Socket进行网络传输文件,一般情况下,大家会首先考虑使用.NET自带的Socket.SendFile Method (String)这个方法。不过这个方法没有相应的文件接受方法,而且据说会有8KB的限制。所以,我尝试了另外一种方法,发现效果不错。下面,我就来简单介绍一下其原理。
      Socket.Send()和Socket.Receive()方法都是传递byte[]的,所以就要想办法把文件给变成byte[]。一开始试过用StreamReader来读取string,然后用Encoding来进行编码得到byte[],接收以后再还原成string写入文件。结果发现不可行,只有纯文本文件以这种方法传输是正常的。
      无奈之下,只好另想办法。后来在File类下找到了这两个方法——File.ReadAllBytes()和File.WriteAllBytes()。试了一下用这两个方法来把文件变成byte[],再把byte[]还原成文件,结果成功了!(试过了传输图片和rar压缩文件,都OK!)/**************************************************
     * Class Name:  MyRenFramework.NetWork.SynchronousSocket
     * Description: The socket does socket communication
     *              in the Synchronous way.
     *              It is better used as a server socket.
     * Create By:   Steven Mo
     * Version:     2008-01
     **************************************************/
    using System;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;namespace MyRenFramework.NetWork
    {
        /// <summary>
        /// SynchronousSocket
        /// </summary>
        public class SynchronousSocket
        {
            private const int BUFFER_SIZE = 65536;
            private const int CONNECTED_WAITTIME = 50;        private const string END_OF_STRING = "$EOS$";
            private const int LISTEN_BACKLOG = 100;
            private IPEndPoint _localEndPoint;
            private IPAddress _localIpAddress;
            private IPEndPoint _remoteEndPoint;
            public delegate void AcceptedFileSavedEventHandler(string fileName);        public delegate void SocketConnectedEventHandler(Socket connectedSocket);        public delegate void StringReceivedEventHandler(Socket connectedSocket, string receivedData);
            public delegate void StringSentEventHandler(Socket connectedSocket, int sentBytes);
            public event SocketConnectedEventHandler SocketConnected;
            public event StringReceivedEventHandler StringReceived;
            public event StringSentEventHandler StringSent;
            public event AcceptedFileSavedEventHandler AcceptedFileSaved;        public SynchronousSocket()
            {
                _localIpAddress = IP.GetLocalIP();
            }
            public void StartListening(int localPort)
            {
                try
                {
                    _localEndPoint = new IPEndPoint(_localIpAddress, localPort);                // Create a TCP/IP listener.
                    Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);                listener.Bind(_localEndPoint);
                    listener.Listen(LISTEN_BACKLOG);                while (true)
                    {
                        Socket connectedSocket = listener.Accept();                    // Wait for the connection to be stabilized.
                        Thread.Sleep(CONNECTED_WAITTIME);                    // Call the SocketConnected event.
                        SocketConnected(connectedSocket);
                    }
                }
                catch
                {
                    return;
                }
            }
            public void StartConnecting(string remoteHostNameOrAddress, int remotePort)
            {
                try
                {
                    IPAddress ipAddress = IP.GetRemoteIpAddress(remoteHostNameOrAddress);
                    _remoteEndPoint = new IPEndPoint(ipAddress, remotePort);                // Create a TCP/IP client.
                    Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);                // Connect to the remote endpoint.
                    client.Connect(_remoteEndPoint);                // Wait for the connection to be stabilized.
                    Thread.Sleep(CONNECTED_WAITTIME);                // Call the SocketConnected event.
                    SocketConnected(client);
                }
                catch
                {
                    return;
                }
            }        private int SendBytes(Socket connectedSocket, byte[] bytes)
            {
                int bytesSent = 0;
                while (bytesSent < bytes.Length)
                {
                    int size;
                    if (bytes.Length - bytesSent >= BUFFER_SIZE)
                    {
                        size = BUFFER_SIZE;
                    }
                    else
                    {
                        size = bytes.Length - bytesSent;
                    }
                    bytesSent += connectedSocket.Send(bytes, bytesSent, size, SocketFlags.None);
                    Thread.Sleep(10);
                }
                Thread.Sleep(1000);
                return bytesSent;
            }
            public void SendData(Socket connectedSocket, String data)
            {
                try
                {
                    // Convert the string data to byte data using Unicode encoding.
                    byte[] byteData = Encoding.Unicode.GetBytes(data + END_OF_STRING);                // Begin sending the data to the remote device.
                    int bytesSent = SendBytes(connectedSocket, byteData);                // Call the StringSent event.
                    StringSent(connectedSocket, bytesSent - END_OF_STRING.Length);
                }
                catch
                {
                    return;
                }
            }
            public void TransmitFile(Socket connectedSocket, string fileName)
            {
                try
                {
                    byte[] fileData = File.ReadAllBytes(fileName);
                    int fileSize = fileData.Length;
                    byte[] byteSize = Encoding.Unicode.GetBytes(fileSize + END_OF_STRING);                // Send the size of the byte array.
                    connectedSocket.Send(byteSize, 0, byteSize.Length, SocketFlags.None);                // Send the data of the file.
                    SendBytes(connectedSocket, fileData);
                }
                catch
                {
                    return;
                }
            }
            public void AcceptFile(Socket connectedSocket, string fileName)
            {
                try
                {
                    byte[] bytes = new Byte[BUFFER_SIZE];
                    byte[] fileData;
                    int fileSize;
                    int receivedBytes = 0;                // Receive the size of the byte array.
                    while (true)
                    {
                        String receivedData = string.Empty;
                        int bytesRec = connectedSocket.Receive(bytes);
                        receivedData += Encoding.Unicode.GetString(bytes, 0, bytesRec);
                        if (receivedData.IndexOf(END_OF_STRING) > -1)
                        {
                            receivedData = receivedData.Replace(END_OF_STRING, string.Empty);
                            fileSize = Convert.ToInt32(receivedData);
                            fileData = new byte[fileSize];
                            break;
                        }
                    }                // Receive the data of the file.
                    while (receivedBytes < fileSize)
                    {
                        int bytesRec = connectedSocket.Receive(bytes);
                        if (bytesRec < BUFFER_SIZE)
                        {
                            for (int i = receivedBytes, j = 0; i < fileSize && j < bytesRec; i++, j++)
                            {
                                fileData[i] = bytes[j];
                            }
                        }
                        else
                        {
                            bytes.CopyTo(fileData, receivedBytes);
                        }
                        receivedBytes += bytesRec;
                    }                // Save file.
                    File.WriteAllBytes(fileName, fileData);                // Call the AcceptedFileSaved event.
                    AcceptedFileSaved(fileName);
                }
                catch
                {
                    return;
                }
            }
            public void ReceiveData(Socket connectedSocket)
            {
                try
                {
                    String receivedData = string.Empty;
                    byte[] bytes = new Byte[BUFFER_SIZE];                while (true)
                    {
                        int bytesRec = connectedSocket.Receive(bytes);
                        receivedData += Encoding.Unicode.GetString(bytes, 0, bytesRec);
                        if (receivedData.IndexOf(END_OF_STRING) > -1)
                        {
                            // Call the StringReceived event.
                            receivedData = receivedData.Replace(END_OF_STRING, string.Empty);
                            StringReceived(connectedSocket, receivedData);
                            break;
                        }
                    }
                }
                catch
                {
                    return;
                }
            }        #endregion
        }
    }
      

  2.   

    http://hi.baidu.com/xiaopengzyz/blog/item/cd09380e1a3c83e7aa64571d.html
      

  3.   

       流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。流式是一种面向连接的Socket,针对于面向连接的TCP服务应用;数据报式Socket是一种无连接的Socket,对应于无连接的UDP服务应用。   Visual C#中操作Socket: 虽然Visual C#可以使用NetworkStream来传送、接收数据,但NetworkStream在使用中有很大的局限性,利用NetworkStream只能传送和接收字符类型的数据,如果要传送的是一些复杂的数据如:二进制数据等,它就显得能力有限了。但使用NetworkStream在处理自身可操作数据时,的确要比Socket方便许多。Socket(套接字)几乎可以处理任何在网络中需要传输的数据类型。
      

  4.   

    networkstream是TcpClient中对socket的封装,其底层还是send,只不过NetworkStream使用了更容易操作的界面把细节封装起来,如果你认为自己写socket收发信息的程序比微软的牛,你就可以放弃TcpClient而直接使用低级的socket方式。
      

  5.   

    NetWorkStream继承System.IO.Stream,而Stream从基类上根源上就有二进制数组以及单个字节输入输出方法,因此NetWorkStream是Stream的扩展。
      

  6.   

    让我们看看源代码,NetworkStream重写的Stream的Write方法:public override void Write(byte[] buffer, int offset, int size)
    {
        if (this.m_CleanedUp)
        {
            throw new ObjectDisposedException(base.GetType().FullName);
        }
        if (buffer == null)
        {
            throw new ArgumentNullException("buffer");
        }
        if ((offset < 0) || (offset > buffer.Length))
        {
            throw new ArgumentOutOfRangeException("offset");
        }
        if ((size < 0) || (size > (buffer.Length - offset)))
        {
            throw new ArgumentOutOfRangeException("size");
        }
        if (!this.CanWrite)
        {
            throw new InvalidOperationException(SR.GetString("net_readonlystream"));
        }
        Socket streamSocket = this.m_StreamSocket;
        if (streamSocket == null)
        {
            throw new IOException(SR.GetString("net_io_writefailure", new object[] { SR.GetString("net_io_connectionclosed") }));
        }
        try
        {
            streamSocket.Send(buffer, offset, size, SocketFlags.None);
        }
        catch (Exception exception)
        {
            if (((exception is ThreadAbortException) || (exception is StackOverflowException)) || (exception is OutOfMemoryException))
            {
                throw;
            }
            throw new IOException(SR.GetString("net_io_writefailure", new object[] { exception.Message }), exception);
        }
        catch
        {
            throw new IOException(SR.GetString("net_io_writefailure", new object[] { string.Empty }), new Exception(SR.GetString("net_nonClsCompliantException")));
        }
    }
    可以看到NetworkStream中仅从这个方法来看,最终就是调用socket的send,不同只是它封装了异常处理机制。