C#SOCKET類封裝,可發送文字圖片,斷開自動連接(有問題)

自己的一個比較完整的功能

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using System.Text;
using System.IO;
using System.Data;
using System.Drawing;
using System.Net;
using System.Net.Sockets;

namespace NAL
{
    public delegate void ReceivedBitmapHandler(Bitmap bitmap);
    public delegate void ReceivedMsgHandler(string str);

    public class TransferHandler
    {
        private int port = 8089;
        private IPEndPoint listenEP = null;
        private IPEndPoint serverEP = null;
        private Socket _listener = null;
        private Socket remoteClient = null;
        private Socket _client = null;
        public event ReceivedBitmapHandler ReceivedBitmap;
        public event ReceivedMsgHandler ReceivedMsg;


        //初始化
        public TransferHandler(Socket client)
        {
            _client = client;
        }

        //初始化IP,端口,SOCKET
        public TransferHandler(string serverIP,int nport)
        {
            serverEP = new IPEndPoint(
                IPAddress.Parse(serverIP),
                port);

            this.port = nport;
        }

        //監聽
        public void StartListen()
        {
            listenEP = new IPEndPoint(Dns.GetHostByName(Dns.GetHostName()).AddressList[0].Address, port);
            _listener = new Socket(
                AddressFamily.InterNetwork,
                SocketType.Stream,
                ProtocolType.Tcp);
            _listener.Bind(listenEP);
            _listener.Listen(-1);
            _listener.BeginAccept(
                new AsyncCallback(AcceptCallback),
                null);
        }

        //監聽回調
        private void AcceptCallback(IAsyncResult iar)
        {
            try
            {
                remoteClient = _listener.EndAccept(iar);
                this.BeginReceive();
            }
            catch (Exception err)
            {
                //客戶端斷開後,自動重新監聽
                _listener.BeginAccept(
                new AsyncCallback(AcceptCallback),
                null);
                return;
            }
        }

        //執行異步連接
        public void BeginConnectServer()
        {
            _client = new Socket(
                AddressFamily.InterNetwork,
                SocketType.Stream,
                ProtocolType.Tcp);
            _client.BeginConnect(serverEP, new AsyncCallback(ConnectCallback), null);
        }

        //異步連接回調
        private void ConnectCallback(IAsyncResult iar)
        {
            try
            {
                _client.EndConnect(iar);
                this.BeginReceive();
            }
            catch (Exception err)
            {
                //獲取連接異常,重新連接
                _client.Close();
                this.BeginConnectServer();
                return;
            }
        }

        //接收信息
        public void BeginReceive() 
        {
            byte[] buffer = new byte[9];
            //由於long佔8位字節,所以先獲取前8位字節數據,標識位1位
            IAsyncResult iar = _client.BeginReceive(
                buffer,
                0,
                buffer.Length,
                SocketFlags.None,
                null,
                null);
            int len = _client.EndReceive(iar);
            int offset = 1;
            int length = BitConverter.ToInt32(buffer, offset);

            if (buffer[0] == 0)
            {
                ReceiveMsg(length);
            }
            if (buffer[0] == 1)
            {
                //先獲取文件長度
                ReceiveFile(length);
            }

            BeginReceive();  //繼續接收
        }

        //接收文件
        private void ReceiveFile(long filelen)
        {
            MemoryStream ms = new MemoryStream();
            int bytesRead = 0;
            long count = 0;
            byte[] buffer = new byte[8*1024];

            while (count != filelen)
            {
                bytesRead = _client.Receive(buffer, buffer.Length, 0);
                ms.Write(buffer, 0, bytesRead);
                count += bytesRead;
            }
            this._msimage = ms;
            ReceivedBitmap(new Bitmap(ms));
        }

        //接收消息
        private void ReceiveMsg(long strlong)
        {
            byte[] buffer = new byte[1024];
            string str = string.Empty;

            _client.Receive(buffer);
            str = Encoding.Default.GetString(buffer);
            _strbuffer = Encoding.Default.GetString(buffer);
            ReceivedMsg(str);
        }

        //發送消息
        public void SendMsg(string msg)
        {
            byte[] arrClientMsg = Encoding.UTF8.GetBytes(msg);
            byte[] len = BitConverter.GetBytes(msg.Length);
            byte[] arrClientSendMsg = new byte[arrClientMsg.Length+9];
            arrClientSendMsg[0] = 0;
            Buffer.BlockCopy(len,0,arrClientSendMsg,1,len.Length);
            Buffer.BlockCopy(arrClientMsg, 0, arrClientSendMsg, 9, arrClientMsg.Length);

             try
             {
                _client.BeginSend(arrClientSendMsg, 0, arrClientSendMsg.Length,
                                SocketFlags.None, new AsyncCallback(SendMsgCallback), null);
             }
             catch(SocketException ex)
             {
                 //可以在此處添加重新連接
                 string str = ex.ToString();
             }
        }

        //發送消息回調
        private void SendMsgCallback(IAsyncResult iar)
        {
            _client.EndSend(iar);
        }

        //發送文件
        public void SendFile(string filename)
        {
            FileInfo fi = new FileInfo(filename);
            byte[] zero = {1};
            byte[] len = BitConverter.GetBytes(fi.Length);
            byte[] all = new byte[zero.Length+len.Length];
            zero.CopyTo(all, 0);
            len.CopyTo(all, zero.Length);

            try
            {
                //首先把文件長度發送過去
                _client.BeginSendFile(filename,
                                all,
                                null,
                                TransmitFileOptions.UseDefaultWorkerThread,
                                new AsyncCallback(SendFileCallback),
                                null);
            }
            catch(SocketException ex)
            {
                //可以在此處添加重新連接
                return;
            }
        }

        //發送文件回調
        private void SendFileCallback(IAsyncResult iar)
        {
            _client.EndSendFile(iar);
        }

        #region 屬性
        private MemoryStream _msimage = null;
        private string _strbuffer = null;
        //圖片 流文件
        public MemoryStream MSImage
        {
            get
            {
                return _msimage;
            }
        }

        //字符串
        public string StrBuffer
        {
            get
            {
                return _strbuffer;
            }
        }
        #endregion

    }
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章