最近做項目中往雲端伺服器上傳資源包文件的時候用到了Socket的通訊,便想把我是如何運用的和大家一起分享!這也是我的第一篇技術分享,哈哈,希望大家多多指點,我這裡只是客戶端的操作,所以只貼客戶端的代碼:
public class SocketHelper { private IPAddress ip = null; private int port = 0; private Socket socket = null; private static ManualResetEvent connectDone = new ManualResetEvent(false); private static ManualResetEvent sendDone = new ManualResetEvent(false); private static ManualResetEvent receiveDone = new ManualResetEvent(false); public SocketHelper(IPAddress ip, int port) { this.ip = ip; this.port = port; } public void StartRun(string _filePath, string _fileName, string _sourceId, string _userId, string _bookId, long _timeStamp, string _type) { try { IPEndPoint remoteEP = new IPEndPoint(ip, port); Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client); connectDone.WaitOne(); if (client.Connected) { //client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 10000000);//5秒超時 long _contenLength = ContentLength(_filePath + ".zip"); string head = "Content-Length=" + _contenLength + ";filename=" + _fileName + ";sourceid=" + _sourceId + ";userid=" + _userId + ";bookid=" + _bookId + ";timestamp=" + _timeStamp + ";type=" + _type + ";\r\n"; Send(client, head); sendDone.WaitOne(); Receive(client); receiveDone.WaitOne(); SendFile(0, client, _filePath + ".zip"); receiveDone.Reset(); Receive(client); receiveDone.WaitOne(); client.Shutdown(SocketShutdown.Both); client.Close(); } } catch (Exception e) { Console.WriteLine(e.ToString()); } } private void ConnectCallback(IAsyncResult ar) { try { Socket client = (Socket)ar.AsyncState; client.EndConnect(ar); connectDone.Set(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } private void Receive(Socket client) { try { StateObject state = new StateObject(); state.workSocket = client; client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); } catch (Exception e) { Console.WriteLine(e.ToString()); } } private void ReceiveCallback(IAsyncResult ar) { try { StateObject state = (StateObject)ar.AsyncState; Socket client = state.workSocket; int bytesRead = client.EndReceive(ar); if (bytesRead > 0) { string aa = Encoding.UTF8.GetString(state.buffer, 0, bytesRead); receiveDone.Set(); } else { // All the data has arrived; put it in response. if (state.sb.Length > 1) { //response = state.sb.ToString(); } // Signal that all bytes have been received. receiveDone.Set(); } } catch (Exception ex) { throw new Exception(string.Format("{0} 伺服器連接中斷", ex.Message)); } } /// <summary> /// 文件流發送 /// </summary> /// <param name="_offset"></param> /// <param name="_client"></param> /// <param name="_path"></param> private void SendFile(long _offset, Socket _client, string _path) { using (FileStream stream = new FileStream(_path, FileMode.Open)) { //文件指針指向0位置 stream.Seek(_offset, SeekOrigin.Begin); NetworkStream netStream = new NetworkStream(_client); int length; byte[] buf = new byte[1024]; while ((length = stream.Read(buf, 0, buf.Length)) > 0) { netStream.Write(buf, 0, length); netStream.Flush(); } } } /// <summary> /// 獲得資源包的大小 /// </summary> /// <param name="path"></param> /// <returns></returns> private long ContentLength(string path) { long _contenLength = 0; using (FileStream stream = new FileStream(path, FileMode.Open)) { _contenLength = stream.Length; } return _contenLength; } /// <summary> /// 協議頭文件的發送 /// </summary> /// <param name="client"></param> /// <param name="data"></param> private void Send(Socket client, String data) { byte[] byteData = Encoding.UTF8.GetBytes(data); client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client); } private void SendCallback(IAsyncResult ar) { try { Socket client = (Socket)ar.AsyncState; int bytesSent = client.EndSend(ar); sendDone.Set(); } catch (Exception ex) { throw new Exception(string.Format("{0} 發送回調失敗", ex.Message)); } } }