客户端要向服务端发送命令,然后等待服务端返回数据,接收后直接存成文件,而不用管到底接收的是什么数据,具体的数据分析另外做。
第一次整异步的东西,根本搞不明白,网上的大都不很清晰
我在这里问一下,高人给个清晰的说法
我先说下我的流程,大家指点:
首先定义了一个socket 
private Socket ServerSocket;//全局的
private byte[] data = new byte[9006];
private int size = 9006;客户端界面有连接按钮(可能连接到不同服务器),该链接代码:
private void buttonConnect_Click(object sender, EventArgs e)
        {
            try
            {
                IPAddress ipaddr = IPAddress.Parse(textBoxIP.Text.Trim());
                int port = Convert.ToInt32(textBoxPort.Text.Trim());                labelConnState.Text = "连接中.....";
                ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint iep = new IPEndPoint(ipaddr, port);                ServerSocket.BeginConnect(iep, new AsyncCallback(ConnectCallback), ServerSocket);
            }
            catch (Exception ex)
            {                MessageBox.Show(ex.ToString());
            }
        }
 private void ConnectCallback(IAsyncResult iar)
        {
            try
            {
                Socket conSocket = (Socket)iar.AsyncState;//这里是新建socket吗,还是用全局那个                conSocket.EndConnect(iar);
                SetConnectText("连接到" + conSocket.RemoteEndPoint.ToString());
                //conSocket.BeginReceive(data, 0, size, SocketFlags.None, new AsyncCallback(ReceiveCallback), conSocket);//这里需要调用接收吗?需要的话是使用这个socket吗?            }
            catch (Exception ex)
            {
                SetConnectText(ex.Message.ToString());
            }
        }发送按钮:
ServerSocket.BeginSend(SendByte, 0, SendByte.Length, SocketFlags.None, new AsyncCallback(SendCallback), ServerSocket); //SendByte是一个字节数组,里面是我发送的命令
  private void SendCallback(IAsyncResult iar)
        {
            try
            {
                Socket SendSocket = (Socket)iar.AsyncState;//这里socket是否新建还是用全局的那个                int Send = SendSocket.EndSend(iar);                StateObject so = new StateObject();
                ServerSocket.BeginReceive(data, 0, size, SocketFlags.None, new AsyncCallback(ReceiveCallback), ServerSocket);//这里用新建的socket还是全局这个ServerSocket,调用ReceiveCallback对吗?            }
            catch (Exception ex)
            {                SetConnectText(ex.Message.ToString());
            }
            
        }private void ReceiveCallback(IAsyncResult iar)
        {
            Socket recvSocket = (Socket)iar.AsyncState;//新建吗?            int rev = recvSocket.EndReceive(iar);
            StringBuilder sb = new StringBuilder();            if (rev > 0)
            {
                NetworkStream ns = new NetworkStream(recvSocket);
                ns.Read(data, 0, rev);
               // sb.Append(BitConverter.ToString(data));
               
                FileStream fs = new FileStream(@"D:\Recv.txt", FileMode.Append, FileAccess.Write, FileShare.Read);
                BinaryWriter bw = new BinaryWriter(fs);
                bw.Write(data);
                fs.Close();
                bw.Close();//这里存文件会出现文件正在使用,而不能写的情况。难道上次没写完,下次就开始写了吗?                try
                {
                    ServerSocket.BeginReceive(data, 0, size, SocketFlags.None, new AsyncCallback(ReceiveCallback), ServerSocket);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }
            else
            {
                ServerSocket.Shutdown(SocketShutdown.Both);
                ServerSocket.Close();            }
           
        }

解决方案 »

  1.   

    Why?
    难道是你水平高到不屑于解释这些问题吗
      

  2.   

    Socket用一个。
    文件正在被使用是第一次写就有的问题还是每次都出?
    我觉得你接受的部分没把数据接收全
    发多少 接多少
    内容的长度也在发送消息的头就可以
      

  3.   

    Socket用一个。
    文件正在被使用是第一次写就有的问题还是每次都出?
    我觉得你接受的部分没把数据接收全
    发多少 接多少
    内容的长度也在发送消息的头就可以
      

  4.   

    Socket用一个。
    文件正在被使用是第一次写就有的问题还是每次都出?
    我觉得你接受的部分没把数据接收全
    发多少 接多少
    内容的长度也在发送消息的头就可以
      

  5.   

    Socket用一个。
    文件正在被使用是第一次写就有的问题还是每次都出?
    我觉得你接受的部分没把数据接收全
    发多少 接多少
    内容的长度也在发送消息的头就可以
      

  6.   

    socket的话用一个就行吗?
    文件正常使用是不是每次都出现,有时候没出现,有时候就出现
    接收长度怎么设置
      

  7.   

    现在接收写文件没问题
    还是放到原来那个地方
    写修改bw.Write(data, 0, rev);成读的长度
    不过接收总达不到预期期望的
    发送过来开始一段的数据还是丢失了
      

  8.   

    //这里用新建的socket还是全局这个ServerSocket,调用ReceiveCallback对吗?
    ServerSocket.BeginReceive(data, 0, size, SocketFlags.None, new AsyncCallback(ReceiveCallback), ServerSocket);
    你在上面这行代码中,使用了下面的BeginReceive方法
    BeginReceive(array<Byte>[]()[], Int32, Int32, SocketFlags, AsyncCallback, Object) 所以当你在ReceiveCallback方法中,这样处理时:
    Socket recvSocket = (Socket)iar.AsyncState;
    int rev = recvSocket.EndReceive(iar);数据已经被接收到data中了!然后你这样去写入接收到的数据:
                    //下面两行代码,没有用,是多余的
                    NetworkStream ns = new NetworkStream(recvSocket);
                    ns.Read(data, 0, rev);
                   // sb.Append(BitConverter.ToString(data));                FileStream fs = new FileStream(@"D:\Recv.txt", FileMode.Append, FileAccess.Write, FileShare.Read);
                    BinaryWriter bw = new BinaryWriter(fs);
                    bw.Write(data);
                    
                    fs.Close();
                    bw.Close();//这里存文件会出现文件正在使用,而不能写的情况。难道上次没写完,下次就开始写了吗?
                    
    你在fs.Close()之前加两行代码:
    bw.Flush();
    fs.Flush();
    最后一个问题,是你的代码大问题没有,你说数据接收不完全,是什么时候发生的,是否发送的数据超过了data的大小?
    private byte[] data = new byte[9006];

    还有回答你的代码中,注释里面的多个问题,都提到了用那个socket,我告诉你ServerSocket.BeginReceive后,你在ReceiveCallback方法中:
    Socket recvSocket = (Socket)iar.AsyncState
    得到的recvSocket 就是ServerSocket,所以你不要担心用哪个!
      

  9.   

    非常感谢(阿捷)的回答
    明白了许多
    继续问下
    异步中需要使用 ManualResetEvent 类来控制线程的执行吗
      

  10.   

    使用BeginReceive开始接收后要有对应的EndReceive来结束接收吧
    Beginconnect和 BeginSend也一样
      

  11.   

    connect要是end掉的话那怎么发送接收数据
    我的send的回调函数中有end语句的
    接收回调函数中也有end语句的,大哥你是没仔细看啊