C# .NET Socket封装
Socket封装,支持多客户端,支持大文件传输,支持多线程并发,对较大的Socket包进行分块传输。
封装所要达到的效果,是可以像下面这样使用Socket和服务端通信,调用服务端的方法,让你在使用Socket的时候,感觉不到Socket的存在,就像是调用本地方法一样,并且支持ref参数和out参数:
DemoService demoService = new DemoService();
DemoService2 demoService2 = new DemoService2();
string result = demoService.Test("测试DemoService", );
demoService.Test2("测试DemoService", );
string result2 = demoService2.RunTest("测试DemoService2", );
一、数据结构:
CmdType:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace DataStruct
{
/// <summary>
/// cmd类型
/// </summary>
public enum CmdType
{
/// <summary>
/// 执行方法
/// </summary>
RunFunction = ,
/// <summary>
/// 心跳
/// </summary>
Heartbeat =
}
}
SocketData:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace DataStruct
{
/// <summary>
/// Socket数据
/// </summary>
[Serializable]
public class SocketData
{
/// <summary>
/// 命令类型
/// </summary>
public CmdType cmdType { get; set; }
/// <summary>
/// 类名
/// </summary>
public string className { get; set; }
/// <summary>
/// 方法名
/// </summary>
public string functionName { get; set; }
/// <summary>
/// 方法参数
/// </summary>
public object[] funParam { get; set; }
}
}
SocketResult:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DataStruct
{
/// <summary>
/// Socket返回
/// </summary>
[Serializable]
public class SocketResult
{
/// <summary>
/// 方法返回值
/// </summary>
public object returnValue { get; set; }
/// <summary>
/// 方法参数
/// </summary>
public object[] param { get; set; }
}
}
FunctionUtil(根据SocketData执行服务端的方法):
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks; namespace DataStruct.Utils
{
/// <summary>
/// 执行方法
/// </summary>
public class FunctionUtil
{
/// <summary>
/// 执行方法
/// </summary>
public static object RunFunction(string applicationPath, SocketData socketData)
{
Assembly assembly = Assembly.LoadFile(Path.Combine(applicationPath, "DataService.dll"));
object classObj = assembly.CreateInstance("DataService." + socketData.className);
Type type = classObj.GetType();
MethodInfo methodInfo = type.GetMethod(socketData.functionName);
ParameterInfo[] parameterInfoArr = methodInfo.GetParameters();
object result = methodInfo.Invoke(classObj, socketData.funParam);
SocketResult socketResult = new SocketResult();
socketResult.returnValue = result;
socketResult.param = new object[socketData.funParam.Length];
object paramObj;
for (int i = ; i < parameterInfoArr.Length; i++)
{
paramObj = socketData.funParam[i];
if (parameterInfoArr[i].ParameterType.IsByRef || parameterInfoArr[i].IsOut)
{
socketResult.param[i] = paramObj;
}
else
{
socketResult.param[i] = null;
}
}
return socketResult;
}
}
}
二、Socket通信封装:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using DataStruct.Utils; namespace DataStruct
{
/// <summary>
/// Socket封装
/// </summary>
public static class SocketHelper
{
#region 变量
private static object _lockSend = new object();
private static Socket serverSocket;
private static Socket clientSocket;
private static List<Socket> clientList = new List<Socket>();
private static System.Timers.Timer heartbeatTimer;
#endregion #region 启动服务
/// <summary>
/// 启动服务
/// </summary>
public static void StartServer()
{
try
{
int port = Convert.ToInt32(ConfigurationManager.AppSettings["ServerPort"]);
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, port);
serverSocket = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(ipEndPoint);
serverSocket.Listen();
new Thread(new ThreadStart(delegate()
{
while (true)
{
Socket m_Client;
try
{
m_Client = serverSocket.Accept();
m_Client.SendTimeout = ;
m_Client.ReceiveTimeout = ;
m_Client.SendBufferSize = ;
m_Client.ReceiveBufferSize = ;
clientList.Add(m_Client);
LogUtil.Log("监听到新的客户端,当前客户端数:" + clientList.Count);
}
catch { break; } DateTime lastHeartbeat = DateTime.Now;
new Thread(new ThreadStart(delegate()
{
try
{
while (true)
{
byte[] receiveByteArr = null;
try
{
receiveByteArr = Receive(m_Client);
}
catch { break; }
if (receiveByteArr != null)
{
SocketData data = (SocketData)SerializeUtil.Deserialize(receiveByteArr);
if (data.cmdType != CmdType.Heartbeat)
{
object obj = null;
try
{
obj = FunctionUtil.RunFunction(System.Windows.Forms.Application.StartupPath, data);
}
catch (Exception ex)
{
LogUtil.LogError("执行方法出错:" + ex.Message + "\r\n" + ex.StackTrace);
Send(m_Client, SerializeUtil.Serialize("error:执行服务端方法出错"));
}
Send(m_Client, SerializeUtil.Serialize(obj));
LogUtil.Log("接收客户端数据,并向客户端返回数据");
}
else
{
lastHeartbeat = DateTime.Now;
LogUtil.Log("收到心跳包,客户端连接正常");
}
}
else
{
clientList.Remove(m_Client);
LogUtil.Log("客户端正常关闭,当前客户端数:" + clientList.Count);
if (m_Client.Connected) m_Client.Disconnect(false);
m_Client.Close();
m_Client.Dispose();
break;
}
}
}
catch (Exception ex)
{
LogUtil.LogError(ex.Message + "\r\n" + ex.StackTrace);
try
{
Send(m_Client, SerializeUtil.Serialize("error:" + ex.Message));
}
catch { }
}
})).Start(); //检测客户端
new Thread(new ThreadStart(delegate()
{
try
{
while (true)
{
DateTime now = DateTime.Now;
if (now.Subtract(lastHeartbeat).TotalSeconds > )
{
clientList.Remove(m_Client);
LogUtil.Log("客户端已失去连接,当前客户端数:" + clientList.Count);
if (m_Client.Connected) m_Client.Disconnect(false);
m_Client.Close();
m_Client.Dispose();
break;
}
Thread.Sleep();
}
}
catch (Exception ex)
{
LogUtil.LogError("检测客户端出错:" + ex.Message + "\r\n" + ex.StackTrace);
}
})).Start();
}
})).Start();
LogUtil.Log("服务已启动");
}
catch (Exception ex)
{
LogUtil.LogError("启动服务出错:" + ex.Message + "\r\n" + ex.StackTrace);
}
}
#endregion #region 停止服务
/// <summary>
/// 停止服务
/// </summary>
public static void StopServer()
{
try
{
foreach (Socket socket in clientList)
{
if (socket.Connected) socket.Disconnect(false);
socket.Close();
socket.Dispose();
}
clientList.Clear();
if (serverSocket != null)
{
if (serverSocket.Connected) serverSocket.Disconnect(false);
serverSocket.Close();
serverSocket.Dispose();
}
LogUtil.Log("服务已停止");
}
catch (Exception ex)
{
LogUtil.LogError("停止服务出错:" + ex.Message + "\r\n" + ex.StackTrace);
}
}
#endregion #region 连接服务器
/// <summary>
/// 连接服务器
/// </summary>
public static void ConnectServer()
{
try
{
if (clientSocket == null || !clientSocket.Connected)
{
if (clientSocket != null)
{
clientSocket.Close();
clientSocket.Dispose();
}
string ip = ConfigurationManager.AppSettings["ServerIP"];
int port = Convert.ToInt32(ConfigurationManager.AppSettings["ServerPort"]);
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(ip), port);
clientSocket = new Socket(ipep.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
clientSocket.SendTimeout = ;
clientSocket.ReceiveTimeout = ;
clientSocket.SendBufferSize = ;
clientSocket.ReceiveBufferSize = ;
clientSocket.Connect(ipep);
LogUtil.Log("已连接服务器");
}
}
catch (Exception ex)
{
LogUtil.LogError("连接服务器失败:" + ex.Message);
}
}
#endregion #region 断开服务器
/// <summary>
/// 断开服务器
/// </summary>
public static void DisconnectServer()
{
try
{
if (clientSocket != null)
{
if (clientSocket.Connected) clientSocket.Disconnect(false);
clientSocket.Close();
clientSocket.Dispose();
}
LogUtil.Log("已断开服务器");
}
catch (Exception ex)
{
LogUtil.LogError("断开服务器失败:" + ex.Message);
}
}
#endregion #region 心跳
public static void StartHeartbeat()
{
heartbeatTimer = new System.Timers.Timer();
heartbeatTimer.Interval = ;
heartbeatTimer.Elapsed += new System.Timers.ElapsedEventHandler((obj, eea) =>
{
try
{
SocketData data = new SocketData();
data.cmdType = CmdType.Heartbeat;
Send(clientSocket, SerializeUtil.Serialize(data));
}
catch (Exception ex)
{
LogUtil.LogError("向服务器发送心跳包出错:" + ex.Message);
}
});
heartbeatTimer.Start();
}
#endregion #region 停止心跳
public static void StopHeartbeat()
{
heartbeatTimer.Stop();
}
#endregion #region Send
/// <summary>
/// Send
/// </summary>
public static void Send(Socket socket, byte[] data)
{
lock (_lockSend)
{
byte[] lenArr = BitConverter.GetBytes(data.Length);
int sendTotal = ;
while (sendTotal < lenArr.Length)
{
int sendOnce = socket.Send(lenArr, sendTotal, lenArr.Length - sendTotal, SocketFlags.None);
sendTotal += sendOnce;
Thread.Sleep();
}
Thread.Sleep(); int block = ;
int count = (data.Length - ) / block + ;
for (int i = ; i < count; i++)
{
int currentBlock = block;
if (i == count - )
{
currentBlock = data.Length - block * i;
}
sendTotal = ;
while (sendTotal < currentBlock)
{
int sendOnce = socket.Send(data, i * block + sendTotal, currentBlock - sendTotal, SocketFlags.None);
sendTotal += sendOnce;
Thread.Sleep();
}
Thread.Sleep();
}
}
}
#endregion #region Receive
/// <summary>
/// Receive
/// </summary>
private static byte[] Receive(Socket socket)
{
lock (socket)
{
try
{
int block = ;
byte[] buffer = new byte[block];
int receiveCount = socket.Receive(buffer, , block, SocketFlags.None);
if (receiveCount == )
{
return null;
}
else
{
while (receiveCount < block)
{
int revCount = socket.Receive(buffer, receiveCount, buffer.Length - receiveCount, SocketFlags.None);
receiveCount += revCount;
Thread.Sleep();
}
int dataLength = BitConverter.ToInt32(buffer, );
block = ;
receiveCount = ;
byte[] result = new byte[dataLength];
while (receiveCount < dataLength)
{
int revCount = socket.Receive(result, receiveCount, result.Length - receiveCount, SocketFlags.None);
receiveCount += revCount;
Thread.Sleep();
}
try
{
SerializeUtil.Deserialize(result);
}
catch (Exception ex)
{
LogUtil.LogError("数据检验失败!");
string aa = ex.Message;
}
return result;
}
}
catch (Exception ex)
{
LogUtil.LogError("接收数据出错:" + ex.Message + "\r\n" + ex.StackTrace);
return null;
}
}
}
#endregion #region IsZero
/// <summary>
/// IsZero
/// </summary>
private static bool IsZero(byte[] data)
{
bool bl = true;
foreach (byte b in data)
{
if (b != )
{
return false;
}
}
LogUtil.LogError("接收的字节数组内容全是0");
return bl;
}
#endregion #region 请求
/// <summary>
/// 请求
/// </summary>
public static object Request(SocketData data)
{
try
{
ConnectServer(); Send(clientSocket, SerializeUtil.Serialize(data)); byte[] receiveByteArr = null;
receiveByteArr = Receive(clientSocket);
if (receiveByteArr != null)
{
object result = SerializeUtil.Deserialize(receiveByteArr);
if (result.GetType() == typeof(string) && result.ToString().IndexOf("error:") == )
{
string errMsg = result.ToString().Split(':')[];
LogUtil.LogError(errMsg);
throw new Exception(errMsg);
}
return result;
}
else
{
if (clientSocket.Connected) clientSocket.Disconnect(false);
clientSocket.Close();
clientSocket.Dispose();
return Request(data);
}
}
catch (Exception ex)
{
if (clientSocket.Connected) clientSocket.Disconnect(false);
LogUtil.LogError(ex.Message);
throw ex;
}
}
#endregion #region Request 请求
/// <summary>
/// 请求
/// </summary>
public static object Request(string className, string methodName, object[] param)
{
SocketData data = new SocketData();
data.className = className;
data.functionName = methodName;
data.funParam = param;
return Request(data);
}
#endregion }
}
三、服务端的服务接口类:
DemoService:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using DAL;
using Models; namespace DataService
{
/// <summary>
/// socket服务
/// </summary>
public class DemoService
{
public List<BS_NoticeType_ext> GetList(ref PagerModel pager, out string str)
{
NoticeTypeDal noticeTypeDal = new NoticeTypeDal();
str = "测试123";
return noticeTypeDal.GetList(ref pager);
} public string Test(string str, int n)
{
return str + ":" + n;
} public void Test2(string str, int n)
{
string s = str + n;
} public void UploadFile(string fileName, byte[] fileData, int index)
{
string path = @"C:\Documents and Settings\Administrator\桌面\XXPLServer\files\";
//string path = @"D:\_临时文件\文件\";
//string path = @"C:\Users\Administrator\Desktop\suxtest\file\";
//string path = @"C:\Documents and Settings\Administrator\桌面\Server\上传文件\";
if (index == )
{
using (FileStream fs = new FileStream(path + fileName, FileMode.Create, FileAccess.Write))
{
fs.Write(fileData, , fileData.Length);
fs.Close();
}
}
else
{
using (FileStream fs = new FileStream(path + fileName, FileMode.Append, FileAccess.Write))
{
fs.Write(fileData, , fileData.Length);
fs.Close();
}
}
}
}
}
DemoService2:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DataService
{
public class DemoService2
{
public string RunTest(string str, int n)
{
return str + ":" + n;
}
}
}
四、客户端接口类代码:
DemoService:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataStruct;
using Common.Utils;
using System.Reflection;
using Models; namespace ClientService
{
public class DemoService
{
public List<BS_NoticeType_ext> GetList(ref PagerModel pager, out string str)
{
SocketResult result = (SocketResult)ServiceUtil.Request(this.GetType().Name,
MethodBase.GetCurrentMethod().Name,
new object[] { pager, null });
pager = (PagerModel)result.param[];
str = (string)result.param[];
return (List<BS_NoticeType_ext>)result.returnValue;
} public string Test(string str, int n)
{
SocketResult result = (SocketResult)ServiceUtil.Request(this.GetType().Name,
MethodBase.GetCurrentMethod().Name,
new object[] { str, n });
return result.returnValue.ToString();
} public void Test2(string str, int n)
{
SocketResult result = (SocketResult)ServiceUtil.Request(this.GetType().Name,
MethodBase.GetCurrentMethod().Name,
new object[] { str, n });
} public bool UploadFile(string fileName, byte[] fileData, int index)
{
try
{
ServiceUtil.Request(this.GetType().Name,
MethodBase.GetCurrentMethod().Name,
new object[] { fileName, fileData, index });
return true;
}
catch
{
return false;
}
}
}
}
DemoService2:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Common.Utils;
using DataStruct; namespace ClientService
{
public class DemoService2
{
public string RunTest(string str, int n)
{
SocketResult result = (SocketResult)ServiceUtil.Request(this.GetType().Name,
MethodBase.GetCurrentMethod().Name,
new object[] { str, n });
return result.returnValue.ToString();
}
}
}
五:服务端启动服务:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using DataStruct;
using DataStruct.Utils;
using Newtonsoft.Json; namespace XXPLServer
{
public partial class Form1 : Form
{
#region 变量
#endregion #region Form1构造函数
public Form1()
{
InitializeComponent();
}
#endregion #region Form1_Load
private void Form1_Load(object sender, EventArgs e)
{ }
#endregion #region 启动服务
private void btnStartServer_Click(object sender, EventArgs e)
{
btnStopServer.Enabled = true;
btnStartServer.Enabled = false;
SocketHelper.StartServer();
}
#endregion #region 停止服务
private void btnStopServer_Click(object sender, EventArgs e)
{
btnStopServer.Enabled = false;
btnStartServer.Enabled = true;
SocketHelper.StopServer();
}
#endregion #region Form1_FormClosing
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
SocketHelper.StopServer();
System.Environment.Exit();
}
#endregion }
}
六:客户端测试代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using CommonDll;
using DataStruct;
using ClientService;
using System.IO;
using System.Diagnostics;
using Models; namespace XXPLClient
{
public partial class Form1 : Form
{
#region 变量
#endregion #region Form1构造函数
public Form1()
{
InitializeComponent();
}
#endregion #region Form1_Load
private void Form1_Load(object sender, EventArgs e)
{
SocketHelper.ConnectServer(); //连接服务器
SocketHelper.StartHeartbeat(); //心跳
}
#endregion #region Form1_FormClosing
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
SocketHelper.DisconnectServer();
SocketHelper.StopHeartbeat();
System.Environment.Exit();
}
#endregion private void btnTest_Click(object sender, EventArgs e)
{
for (int i = ; i < ; i++)
{
new Thread(new ParameterizedThreadStart((obj) =>
{
try
{
for (int j = ; j < ; j++)
{
DemoService demoService = new DemoService();
DemoService2 demoService2 = new DemoService2();
string str = demoService.Test("测试DemoService", ) + "\r\n" + demoService2.RunTest("测试DemoService2", );
MessageBox.Show(str);
}
}
catch (Exception ex)
{
LogUtil.LogError(ex.Message);
MessageBox.Show(ex.Message);
}
})).Start();
}
} private void btnUpload_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
new Thread(new ParameterizedThreadStart((obj) =>
{
int block = ;
byte[] bArr = new byte[block];
string fileName;
using (FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read))
{
fileName = Path.GetFileName(fs.Name);
long count = (fs.Length - ) / block + ; DemoService demoService = new DemoService();
for (int i = ; i < count; i++)
{
if (i != count - )
{
fs.Read(bArr, , bArr.Length);
}
else
{
int len = (int)(fs.Length - block * i);
bArr = new byte[len];
fs.Read(bArr, , bArr.Length);
}
bool bl = demoService.UploadFile(fileName, bArr, i + );
while (!bl)
{
bl = demoService.UploadFile(fileName, bArr, i + );
LogUtil.LogError("发生错误,重发");
Thread.Sleep();
}
Thread.Sleep();
}
fs.Close();
} MessageBox.Show("成功");
})).Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
} private void button1_Click(object sender, EventArgs e)
{
try
{
DemoService demoService = new DemoService();
PagerModel pager = new PagerModel();
pager.page = ;
pager.rows = ;
string str;
List<BS_NoticeType_ext> list = demoService.GetList(ref pager, out str);
MessageBox.Show(string.Format("数据总条数:{0}\r\n页数:{1}\r\nout参数值:{2}\r\n第一条数据:{3}",
pager.totalRows, pager.pageCount, str, list[].name));
}
catch (Exception ex)
{
string ss = ex.Message;
}
} }
}
七:大文件分块上传:
服务端DemoService添加如下方法:
public void UploadFile(string fileName, byte[] fileData, int index)
{
string path = @"C:\Documents and Settings\Administrator\桌面\XXPLServer\files\";
//string path = @"D:\_临时文件\文件\";
//string path = @"C:\Users\Administrator\Desktop\suxtest\file\";
//string path = @"C:\Documents and Settings\Administrator\桌面\Server\上传文件\";
if (index == )
{
using (FileStream fs = new FileStream(path + fileName, FileMode.Create, FileAccess.Write))
{
fs.Write(fileData, , fileData.Length);
fs.Close();
}
}
else
{
using (FileStream fs = new FileStream(path + fileName, FileMode.Append, FileAccess.Write))
{
fs.Write(fileData, , fileData.Length);
fs.Close();
}
}
}
客户端DemoService添加如下方法:
public bool UploadFile(string fileName, byte[] fileData, int index)
{
try
{
ServiceUtil.Request(this.GetType().Name,
MethodBase.GetCurrentMethod().Name,
new object[] { fileName, fileData, index });
return true;
}
catch
{
return false;
}
}
客户端选择文件上传:
private void btnUpload_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
new Thread(new ParameterizedThreadStart((obj) =>
{
int block = ;
byte[] bArr = new byte[block];
string fileName;
using (FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read))
{
fileName = Path.GetFileName(fs.Name);
long count = (fs.Length - ) / block + ; for (int i = ; i < count; i++)
{
if (i != count - )
{
fs.Read(bArr, , bArr.Length);
}
else
{
int len = (int)(fs.Length - block * i);
bArr = new byte[len];
fs.Read(bArr, , bArr.Length);
}
DemoService demoService = new DemoService();
bool bl = demoService.UploadFile(fileName, bArr, i + );
while (!bl)
{
bl = demoService.UploadFile(fileName, bArr, i + );
LogUtil.LogError("发生错误,重发");
Thread.Sleep();
}
Thread.Sleep();
}
fs.Close();
} MessageBox.Show("成功");
})).Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
C# .NET Socket封装的更多相关文章
- ACE - 代码层次及Socket封装
原文出自http://www.cnblogs.com/binchen-china,禁止转载. ACE源码约10万行,是c++中非常大的一个网络编程代码库,包含了网络编程的边边角角.在实际使用时,并不是 ...
- 跨平台的游戏客户端Socket封装,调整
原文链接:http://www.cnblogs.com/lancidie/archive/2013/04/13/3019359.html 头文件: #pragma once #ifdef WIN32 ...
- Linux C socket 封装
/************************************************************************** * Linux C socket 封装 * 声明 ...
- web前端socket封装库--giraffe
摘要: 最近在做前端的socket消息推送,使用了socket.io.js的最新版本.使用过的都知道socket.io.js是基于消息类型来通信的,如果消息类型多了就很难维护.所以本人就对socket ...
- 一个高性能异步socket封装库的实现思路 (c#)
前言 socket是软件之间通讯最常用的一种方式.c#实现socket通讯有很多中方法,其中效率最高就是异步通讯. 异步通讯实际是利用windows完成端口(IOCP)来处理的,关于完成端口实现原理, ...
- python进阶__用socket封装TCP
想要理解socket协议,点击链接,出门左转 一.TCP 通信的服务器端编程的基本步骤: 服务器端先创建一个 socket 对象. 服务器端 socket 将自己绑定到指定 IP 地址和端口. 服务器 ...
- 从零开始—Socket系统调用和多态封装
1 重新搭建实验环境 前面都是用实验楼环境做的实验,偷的懒总是要还的,这一次重装环境前后花了十几个小时,踩了无数的坑. 1.1 Ubuntu和LINUX内核的区别 Ubuntu是基于LINUX内核编写 ...
- C++ Socket 简单封装
以下代码一部分来自于<网络多人游戏架构与编程>, 其它的都是我瞎写的. 备忘. 一个简单的Socket封装,没有做什么高级的操作(比如IO完成端口等等). 1 #pragma once 2 ...
- 试解析Tomcat运行原理(一)--- socket通讯
关于这篇文章也确实筹划了很久,今天决定开篇写第一篇,说起tomcat首先很容易联想到IIS,因为我最开始使用的就是.net技术,我第一次使用asp写学生成绩管理系统后,很茫然如何让别人都能看到或者说使 ...
随机推荐
- 使用libjpeg.framework压缩UIImage
+(void)writeFile:(NSString *)filePath withQuality:(int)quality { //初始化图片参数 UIImage *image=[UIImage i ...
- TCP/IP, WebSocket 和 MQTT
按照OSI网络分层模型,IP是网络层协议,TCP是传输层协议,而HTTP和MQTT是应用层的协议.在这三者之间, TCP是HTTP和MQTT底层的协议.大家对HTTP很熟悉,这里简要介绍下MQTT.M ...
- 验证码类库CaptchaMvc
CaptchaMvc是一个有弹性的.简单的解决方案,它能够解决你项目中所有与验证码相关的问题.你需要做的所有事情就是向你的项目中添加一个类库,添加之后验证码就准备就绪了.该项目拥有使用验证码所需要的所 ...
- 从“差不多了”到 正式发布 -- 新浪微博WinPhone UWP版诞生记
本文粗略记述了UWP团队从接手新浪微博项目到发布第一版的过程.本文不是技术贴,而是回顾“软件工程周期失控是一种怎样的体验”. 接手新项目:捡了个大便宜 2016年1月份,UWP team开始接手新浪微 ...
- Lesson 6 Percy Buttons
Text I have just moved to a house in Bridge Street. Yesterday a bagger knocked at my door. He asked ...
- Android学习——windows下搭建NDK_r9环境
1. NDK(Native Development Kit) 1.1 NDK简介 Android NDK是一套允许开发人员使用本地代码(如C/C++)进行Android APP功能开发的工具,通过这个 ...
- Qt And MFC UI Layout
界面布局 起初,计算机的交互是通过输入的代码进行的, 慢慢的有了图形之后, 就开始了图形界面的交互. 目前来说还有语音交互, 视频交互等多媒体的交互. 不管哪一种交互, 最终在计算机的角度都是信号的输 ...
- Java,extends,继承
1. 继承的概念: 继承在本职上是特殊--一般的关系.子类继承父类,表明子类是一种特殊的父类,并且具有父类所不具有的一些属性或方法. 2. 继承中的初始化顺序: 从类的结构上而言,其内部可以有如下四种 ...
- Android-Activity-Dialog theme touch outsize
最近遇到一个蛋疼的问题: 一个Activity,主题设置成 Dialog 然后点击外面要求这个Activity 不能关闭. 这下好了,直接在 style 的 theme 里面加一个属性就好了. 加上去 ...
- unity开发相关环境(vs、MonoDevelop)windows平台编码问题
情景描述:最近在做Unity的网络底层,用VS编写源码,MonoDevelop用来Debug,在Flash Builder上搭建的Python做协议生成器,期间有无数次Unity莫名奇妙的的down掉 ...