亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#之Socket操作類實例解析

2020-01-24 02:28:20
字體:
來源:轉載
供稿:網友

本文展示了一個C#的Socket操作類的完整實例,并附帶了用法說明,分享給大家供大家參考之用。具體方法如下:

主要功能代碼如下:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Net.Sockets;using System.Collections;using System.Net;using System.Runtime.Serialization;using System.Runtime.Serialization.Formatters.Binary;using System.IO;using System.Collections.Specialized;using System.Threading;public class DuxSocketClient{ #region 私有字段 /// <summary> /// 設置數據緩沖區大小 默認1024 /// </summary> private static int m_maxpacket = 1024 * 4; public delegate void SendFileProgress(int progress); public delegate void ReceiveFileProgress(int progress); #endregion #region 服務器偵聽 /// <summary> /// 服務器偵聽方法 返回null則說明沒有鏈接上 /// </summary> /// <returns>返回一個套接字(Socket)</returns> public static Socket ListenerSocket(TcpListener listener) {  try  {   Socket socket = listener.AcceptSocket();   return socket;  }  catch  {   return null;  } } /// <summary> /// 服務器偵聽方法 返回null則說明沒有鏈接上 /// </summary> /// <param name="listener"></param> /// <returns>返回一個網絡流</returns> public static NetworkStream ListenerStream(TcpListener listener) {  try  {   TcpClient client = listener.AcceptTcpClient();   return client.GetStream();  }  catch  {   return null;  } } #endregion #region 客戶端連接 public static Socket ConnectSocket(TcpClient tcpclient, IPEndPoint ipendpoint) {  try  {   tcpclient.Connect(ipendpoint);   return tcpclient.Client;  }  catch  {   return null;  } } public static Socket ConnectSocket(TcpClient tcpclient, IPAddress ipadd, int port) {  try  {   tcpclient.Connect(ipadd, port);   return tcpclient.Client;  }  catch  {   return null;  } } public static NetworkStream ConnectStream(TcpClient tcpclient, IPEndPoint ipendpoint) {  try  {   tcpclient.Connect(ipendpoint);   return tcpclient.GetStream();  }  catch  {   return null;  } } public static NetworkStream ConnectStream(TcpClient tcpclient, IPAddress ipadd, int port) {  try  {   tcpclient.Connect(ipadd, port);   return tcpclient.GetStream();  }  catch  {   return null;  } } #endregion #region Socket接收數據 /// <summary> /// 接受固定長度字符串 /// </summary> /// <param name="socket"></param> /// <param name="size"></param> /// <returns></returns> public static byte[] ReceiveFixData(Socket socket, int size) {  int offset = 0;  int recv = 0;  int dataleft = size;  byte[] msg = new byte[size];  while (dataleft > 0)  {   recv = socket.Receive(msg, offset, dataleft, 0);   if (recv == 0)   {    break;   }   offset += recv;   dataleft -= recv;  }  return msg; } /// <summary> /// 接收變長字符串 /// 為了處理粘包問題 ,每次發送數據時 包頭(數據字節長度) + 正文 /// 這個發送小數據 /// 設置包頭的字節為8,不能超過8位數的字節數組 /// </summary> /// <param name="socket"></param> /// <returns>byte[]數組</returns> public static byte[] ReceiveVarData(Socket socket) {  //每次接受數據時,接收固定長度的包頭,包頭長度為8  byte[] lengthbyte = ReceiveFixData(socket, 8);  //length得到字符長度 然后加工處理得到數字  int length = GetPacketLength(lengthbyte);  //得到正文  return ReceiveFixData(socket, length);   } /// <summary> /// 接收T類對象,反序列化 /// </summary> /// <typeparam name="T">接收T類對象,T類必須是一個可序列化類</typeparam> /// <param name="socket"></param> /// <returns></returns> public static T ReceiveVarData<T>(Socket socket) {  //先接收包頭長度 固定8個字節  byte[] lengthbyte = ReceiveFixData(socket, 8);  //得到字節長度  int length = GetPacketLength(lengthbyte);  byte[] bytecoll = new byte[m_maxpacket];  IFormatter format = new BinaryFormatter();  MemoryStream stream = new MemoryStream();  int offset = 0; //接收字節個數  int lastdata = length; //還剩下多少沒有接收,初始大小等于實際大小  int receivedata = m_maxpacket; //每次接收大小  //循環接收  int mark = 0; //標記幾次接收到的數據為0長度  while (true)  {   //剩下的字節數是否小于緩存大小   if (lastdata < m_maxpacket)    {    receivedata = lastdata; //就只接收剩下的字節數   }   int count = socket.Receive(bytecoll,0,receivedata,0);   if (count > 0)   {    stream.Write(bytecoll, 0, count);    offset += count;    lastdata -= count;    mark = 0;   }   else   {    mark++;    if (mark == 10)    {     break;    }   }   if (offset == length)   {    break;   }  }  stream.Seek(0, SeekOrigin.Begin); //必須要這個 或者stream.Position = 0;  T t = (T)format.Deserialize(stream);  stream.Close();  return t; } /// <summary> /// 在預先得到文件的文件名和大小 /// 調用此方法接收文件 /// </summary> /// <param name="socket"></param> /// <param name="path">路徑必須存在</param> public static bool ReceiveFile(Socket socket, string path, string filename, long size,ReceiveFileProgress progress) {  bool ret = false;  if (Directory.Exists(path))  {   //主要是防止有重名文件   string savepath = GetPath(path, filename); //得到文件路徑   //緩沖區   byte[] file = new byte[m_maxpacket];   int count = 0; //每次接收的實際長度   int receivedata = m_maxpacket; //每次要接收的長度   long offset = 0; //循環接收的總長度   long lastdata = size; //剩余多少還沒接收   int mark = 0;   using (FileStream fs = new FileStream(savepath, FileMode.OpenOrCreate, FileAccess.Write))   {    if (size > 0)    {     while (true)     {      if (lastdata < receivedata)      {       receivedata = Convert.ToInt32(lastdata);      }      count = socket.Receive(file, 0, receivedata, SocketFlags.None);      if (count > 0)      {       fs.Write(file, 0, count);       offset += count;       lastdata -= count;       mark = 0;      }      else      {       mark++; //連續5次接收為0字節 則跳出循環       if (mark ==10)       {        break;       }      }      //接收進度      if (progress != null)      {       progress(Convert.ToInt32(((Convert.ToDouble(offset) / Convert.ToDouble(size)) * 100)));      }      //接收完畢      if (offset == size)      {       ret = true;       break;      }     }    }    fs.Close();   }  }  return ret; } public static bool ReceiveFile(Socket socket, string path, string filename, long size) {  return ReceiveFile(socket, path, filename, size,null); } /// <summary> /// 預先不知道文件名和文件大小 用此方法接收 /// 此方法對于的發送方法是SendFile() /// </summary> /// <param name="socket"></param> /// <param name="path">要保存的目錄</param> public static void ReceiveFile(Socket socket, string path) {  //得到包頭信息字節數組 (文件名 + 文件大小 的字符串長度)  //取前8位  byte[] info_bt = ReceiveFixData(socket, 8);  //得到包頭信息字符長度  int info_length = GetPacketLength(info_bt);  //提取包頭信息,(文件名 + 文件大小 的字符串長度)  byte[] info = ReceiveFixData(socket, info_length);  //得到文件信息字符串 (文件名 + 文件大小)  string info_str = System.Text.Encoding.UTF8.GetString(info);  string[] strs = info_str.Split('|');  string filename = strs[0]; //文件名  long length = Convert.ToInt64(strs[1]); //文件大小  //開始接收文件  ReceiveFile(socket, path, filename, length); } private static int GetPacketLength(byte[] length) {  string str = System.Text.Encoding.UTF8.GetString(length);  str = str.TrimEnd('*'); ;//("*", "");  int _length = 0;  if (int.TryParse(str, out _length))  {   return _length;  }  else  {   return 0;  } } /// <summary> /// 得到文件路徑(防止有文件名重復) /// 如:aaa.txt已經在directory目錄下存在,則會得到文件aaa(1).txt /// </summary> /// <param name="directory">目錄名</param> /// <param name="file">文件名</param> /// <returns>文件路徑</returns> static int i = 0; static string markPath = String.Empty; public static string GetPath(string directory, string file) {  if (markPath == String.Empty)  {   markPath = Path.Combine(directory, file);  }  string path = Path.Combine(directory, file);  if (File.Exists(path))  {   i++;   string filename = Path.GetFileNameWithoutExtension(markPath) + "(" + i.ToString() + ")";   string extension = Path.GetExtension(markPath);   return GetPath(directory, filename + extension);  }  else  {   i = 0;   markPath = String.Empty;   return path;  } } #endregion #region Socket發送數據 /// <summary> /// 發送固定長度消息 /// 發送字節數不能大于int型最大值 /// </summary> /// <param name="socket"></param> /// <param name="msg"></param> /// <returns>返回發送字節個數</returns> public static int SendFixData(Socket socket, byte[] msg) {  int size = msg.Length; //要發送字節長度  int offset = 0;     //已經發送長度  int dataleft = size;  //剩下字符  int senddata = m_maxpacket; //每次發送大小  while (true)  {   //如過剩下的字節數 小于 每次發送字節數   if (dataleft < senddata)   {    senddata = dataleft;   }   int count = socket.Send(msg, offset, senddata, SocketFlags.None);   offset += count;   dataleft -= count;   if (offset == size)   {    break;   }  }  return offset; } /// <summary> /// 發送變長信息 格式 包頭(包頭占8位) + 正文 /// </summary> /// <param name="socket"></param> /// <param name="contact">發送文本</param> /// <returns></returns> public static int SendVarData(Socket socket, string contact) {  //得到字符長度  int size = System.Text.Encoding.UTF8.GetBytes(contact).Length;  //包頭字符  string length = GetSendPacketLengthStr(size);  //包頭 + 正文  byte[] sendbyte = System.Text.Encoding.UTF8.GetBytes(length + contact);  //發送  return SendFixData(socket, sendbyte); } /// <summary> /// 發送變成信息 /// </summary> /// <param name="socket"></param> /// <param name="bytes"></param> /// <returns></returns> public static int SendVarData(Socket socket, byte[] bytes) {  //得到包頭字節  int size = bytes.Length;  string length = GetSendPacketLengthStr(size);  byte[] lengthbyte = System.Text.Encoding.UTF8.GetBytes(length);  //發送包頭  SendFixData(socket, lengthbyte);  //因為不知道正文是什么編碼所以沒有合并  //發送正文  return SendFixData(socket, bytes); } /// <summary> /// 發送T類型對象,序列化 /// </summary> /// <typeparam name="T">T類型</typeparam> /// <param name="socket"></param> /// <param name="obj">T類型對象,必須是可序列化的</param> /// <returns></returns> public static int SendSerializeObject<T>(Socket socket, T obj) {  byte[] bytes = SerializeObject(obj);  return SendVarData(socket, bytes); } /// <summary> /// 發送文件 /// </summary> /// <param name="socket">socket對象</param> /// <param name="path">文件路徑</param> /// <param name="issend">是否發送文件(頭)信息,如果當前知道文件[大小,名稱]則為false</param> /// <param name="progress"></param> /// <returns></returns> public static bool SendFile(Socket socket, string path,bool issend,SendFileProgress progress) {  bool ret = false;  if (File.Exists(path))  {   FileInfo fileinfo = new FileInfo(path);   string filename = fileinfo.Name;   long length = fileinfo.Length;   //發送文件信息   if (issend)   {    SendVarData(socket, filename + "|" + length);   }   //發送文件   long offset = 0;   byte[] b = new byte[m_maxpacket];   int mark = 0;   using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))   {    int senddata = b.Length;    long i = length;    //循環讀取發送    while (true)    {     int count = fs.Read(b, 0, senddata);     if (count > 0)     {      socket.Send(b, 0, count, SocketFlags.None);      offset += count;      mark = 0;     }     else     {      mark++;      if (mark == 10)      {       break;      }     }     if (progress != null)     {      progress(Convert.ToInt32(((Convert.ToDouble(offset) / Convert.ToDouble(length)) * 100)));     }     if (offset == length)     {      break;     }     Thread.Sleep(50); //設置等待時間,以免粘包    }   }  }  return ret; } /// <summary> /// 發送文件,不需要進度信息 /// </summary> /// <param name="socket">socket對象</param> /// <param name="path">文件路徑</param> /// <param name="issend">是否發生(頭)信息</param> /// <returns></returns> public static bool SendFile(Socket socket, string path,bool issend) {  return SendFile(socket, path, issend, null); } /// <summary> /// 發送文件,不需要進度信息和(頭)信息 /// </summary> /// <param name="socket">socket對象</param> /// <param name="path">文件路徑</param> /// <returns></returns> public static bool SendFile(Socket socket, string path) {  return SendFile(socket, path, false, null); } private static byte[] SerializeObject(object obj) {  IFormatter format = new BinaryFormatter();  MemoryStream stream = new MemoryStream();  format.Serialize(stream, obj);  byte[] ret = stream.ToArray();  stream.Close();  return ret; } private static string GetSendPacketLengthStr(int size) {  string length = size.ToString() + "********"; //得到size的長度  return length.Substring(0, 8); //截取前前8位 } #endregion #region NetworkStream接收數據 //沒寫 #endregion #region NetworkStream發送數據 //沒寫 #endregion}

用法說明:

每個接收的方法都對應著有發送方法

如:

發送方法:

SendFixData(socket,"01");

接收方法:

ReceiveFixData(socket,2); //size 就為2

不知道發送文本長度:

string txt = ????  //不知道有多少字符

發送方法:

SendVarData(socket,txt); //有重載版

接收方法:

ReceiveVarData(socket);

希望本文所述實例對大家C#程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品久久一区| 91sao在线观看国产| 久久久www成人免费精品张筱雨| 91精品在线播放| 欧美中文字幕在线观看| 亚洲色图狂野欧美| 国内外成人免费激情在线视频网站| 97在线日本国产| 成人国产精品久久久久久亚洲| 成人精品福利视频| 日韩欧美综合在线视频| 久久影院模特热| 欧美风情在线观看| 日韩在线www| 欧美激情第三页| 亚洲国产女人aaa毛片在线| 日韩国产欧美精品一区二区三区| 68精品国产免费久久久久久婷婷| 欧美大秀在线观看| 精品高清美女精品国产区| 97免费视频在线播放| 国产欧美日韩最新| 亚洲精品动漫久久久久| 精品人伦一区二区三区蜜桃免费| 精品国产一区二区三区久久狼黑人| 91国产视频在线播放| 97精品视频在线观看| 亚洲国产精彩中文乱码av在线播放| 97在线观看视频| 日韩av在线网址| 欧美色欧美亚洲高清在线视频| 欧美人成在线视频| 欧美日韩国产va另类| 日本免费在线精品| 一区二区三区高清国产| 久久久免费在线观看| 亚洲嫩模很污视频| 精品久久久久久久中文字幕| 亚洲天天在线日亚洲洲精| 国产香蕉一区二区三区在线视频| 欧美亚洲视频在线看网址| 亲子乱一区二区三区电影| 91成人免费观看网站| 青青草国产精品一区二区| 91亚洲精品久久久久久久久久久久| 最近中文字幕mv在线一区二区三区四区| 亚洲国产精品电影| 国产盗摄xxxx视频xxx69| 久久躁狠狠躁夜夜爽| 国产激情999| 日韩电影第一页| 亚洲午夜av久久乱码| 亚洲人成啪啪网站| 亚洲综合中文字幕68页| 久久久久久久久亚洲| 久久午夜a级毛片| 久久精品亚洲热| 国产精品久久久久91| 欧美精品日韩www.p站| 国产一区二区三区视频免费| 91精品国产91久久| 一区二区av在线| 久久精品99久久久久久久久| 久久精品国产久精国产思思| 欧美在线日韩在线| 国产精品专区h在线观看| 欧美日韩亚洲高清| 国产精品入口尤物| 亚洲色图欧美制服丝袜另类第一页| 国产精品一区二区三区毛片淫片| 国产一区二区免费| 精品精品国产国产自在线| 欧美最猛性xxxxx亚洲精品| 91丝袜美腿美女视频网站| 日韩电影中文 亚洲精品乱码| 国产欧美日韩精品专区| 日韩在线视频免费观看高清中文| 日韩少妇与小伙激情| 久青草国产97香蕉在线视频| 91精品国产91久久久| 欧美性极品少妇精品网站| 2019国产精品自在线拍国产不卡| 日韩免费观看在线观看| 疯狂做受xxxx高潮欧美日本| 亚洲天堂视频在线观看| 精品magnet| 91久久久亚洲精品| 欧美成人精品一区二区| 久久久久国产一区二区三区| 欧美亚洲国产成人精品| 亚洲网站视频福利| 97免费视频在线播放| 久久亚洲成人精品| 欧美激情亚洲视频| 亚洲美腿欧美激情另类| 久久人人爽人人爽人人片av高请| 日韩欧美在线观看视频| 欧美成年人视频网站| 亚洲第一网站免费视频| 国产精品亚发布| 久久精品中文字幕一区| 久久精品国产成人| 九九热最新视频//这里只有精品| 欧美在线国产精品| 18性欧美xxxⅹ性满足| 91免费看国产| 亚洲一区制服诱惑| 色小说视频一区| 7m第一福利500精品视频| 日韩在线观看免费高清完整版| 亚洲国产精品久久久久久| 亚洲精品99久久久久| 国产精品亚洲精品| 欧美另类极品videosbest最新版本| 国外成人在线播放| 成人久久久久久| 中文字幕日韩av综合精品| 最新日韩中文字幕| 永久免费精品影视网站| 51ⅴ精品国产91久久久久久| 欧美老女人www| 性视频1819p久久| 欧美另类在线播放| 性欧美xxxx视频在线观看| 欧美日韩亚洲国产一区| 精品久久久久久久久中文字幕| 日韩成人网免费视频| 中文字幕亚洲激情| 91欧美精品午夜性色福利在线| 久久这里有精品| 中文字幕欧美亚洲| 亚洲专区中文字幕| 日本国产精品视频| 91在线无精精品一区二区| 亚洲精品一区二区久| 国产精品黄页免费高清在线观看| 国产在线一区二区三区| 久久精品中文字幕免费mv| 国产欧美精品久久久| 国产精品久久久久免费a∨| 亚洲国产精品成人一区二区| 国产亚洲日本欧美韩国| 亚洲国产精品久久精品怡红院| 久久国产精品久久精品| 欧美精品日韩三级| 欧美色道久久88综合亚洲精品| 欧美精品18videos性欧| 韩国19禁主播vip福利视频| 国产第一区电影| 91精品国产99久久久久久| 日韩av电影院| 日韩精品中文字幕有码专区| 国产性猛交xxxx免费看久久| 国产综合视频在线观看| 伊人久久大香线蕉av一区二区| 亚洲一级免费视频| 在线精品国产欧美| 福利视频导航一区| 色妞色视频一区二区三区四区| 欧美精品在线免费播放| 国产精品免费网站| 色哟哟网站入口亚洲精品| 成人在线播放av| 欧美激情视频网址|