Socket 基础&实例(上)
来源:互联网 发布:codeblocks有mac版吗 编辑:程序博客网 时间:2024/05/16 04:43
Socket 基础知识
TCP/IP层次模型
a. 应用层
b. 传输层 : UDP和TCP(区别即 TCP传输控制协议,是一种提供可靠数据传输的通用协议。
UDP是一个面 向无连接的协议,此处可能解释不太清楚,百度哈。(~ o ~)~zZ)
c. 网络层:通信子网,它通过网络连接交换传输层发出的实体数据。
d. 链路层:是建立在物理传输能力的基础上,以帧为单位传输数据,
它的主要任务就是进行数据封装和数据链接的建立TCP分节传输图解
(每层传输过程中,都将增加分节的头)Socket类型
a. 流式Socket
是一种面向连接的Socket,针对于面向连接的TCP服务应用,安全,但是效率低
b. 数据报式Socket
是一种无连接的Socket,对应于无连接的UDP服务应用,不安全,但效率高组图说明Socket客户端和服务器的连接过程
这就是所谓的三次握手,哈哈。。Socket常用类和方法
相关类:
IPAddress:包含了一个IP地址 IPEndPoint:包含了一对IP地址和端口号
方法:
Socket():创建一个Socket Bind():绑定一个本地的IP和端口号(IPEndPoint) Listen():让Socket侦听传入的连接吃那个病,并指定侦听队列容量 Connect():初始化与另一个Socket的连接 Accept():接收连接并返回一个新的Socket Send():输出数据到Socket Receive():从Socket中读取数据
上方法在Socket连接中基本上都会用到
- 实战部分代码
服务器代码(新建项目的时候,此处是
)
using System;using System.Net;using System.Collections.Generic;using System.Net.Sockets;using System.IO;using System.Text;using System.Threading;using System.Runtime.Serialization.Formatters.Binary;public class Echoserver{ private static int m_SocketCount = 0; private static ManualResetEvent m_ManualResetEvent = new ManualResetEvent(false); //entry point of main method. public static void Main() { IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 10068); Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { serverSocket.Bind(ipEndPoint); serverSocket.Listen(20); Console.WriteLine("Server Start"); while (true) { m_ManualResetEvent.Reset(); //将线程置于非终止状态,也就是等待当前线程完成; serverSocket.BeginAccept(new AsyncCallback(Accept), serverSocket); m_ManualResetEvent.WaitOne(); //阻塞主线程,这里的作用是不退出程序; } } catch (System.Exception ex) { Console.WriteLine("Exception" + ex); } } public static void Accept(IAsyncResult result) { m_ManualResetEvent.Set(); //通知主线程继续; Socket serverSocket = (Socket)result.AsyncState; Console.WriteLine("Accept one Client " + (++m_SocketCount)); //已经Accept客户端之后就停止Accept; Socket receiverSocket = serverSocket.EndAccept(result); //开始Receive; StateObject state = new StateObject(); state.m_CurSocket = receiverSocket; receiverSocket.BeginReceive(state.m_Buffer, 0, StateObject.m_BufferSize, 0, new AsyncCallback(ReceiveCallBack), state); } public static void ReceiveCallBack(IAsyncResult result) { String content = String.Empty; StateObject state = (StateObject)result.AsyncState; Socket receiverSocket = state.m_CurSocket; try { int byteRead = receiverSocket.EndReceive(result); if (byteRead > 0) { //获取数据长度; byte[] datalengtharr = new byte[4]; Buffer.BlockCopy(state.m_Buffer, 0, datalengtharr, 0, 4); int datalength = BitConverter.ToInt32(datalengtharr, 0); Console.WriteLine("receive data length = " + datalength.ToString()); //获取数据主体; byte[] dataarr = new byte[byteRead - 4]; Buffer.BlockCopy(state.m_Buffer, 4, dataarr, 0, byteRead - 4); state.m_StringBuilder.Append(Encoding.ASCII.GetString(dataarr, 0, byteRead - 4)); content = state.m_StringBuilder.ToString(); //判断数据长度,是否接收完全; if (!(byteRead - 4 < datalength)) { Console.WriteLine("Receive " + content.Length + " " + content); //接收完全后发送数据给客户端; Send(receiverSocket, "success from server"); } else { //数据没有接收完,继续接收; receiverSocket.BeginReceive(state.m_Buffer, 0, StateObject.m_BufferSize, 0, new AsyncCallback(ReceiveCallBack), state); } } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } public static void Send(Socket handler, String data) { byte[] byteData = Encoding.ASCII.GetBytes(data); try { handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } public static void SendCallback(IAsyncResult result) { try { Socket handler = (Socket)result.AsyncState; int bytesSend = handler.EndSend(result); Console.WriteLine("Sent {0} bytes to client.", bytesSend); handler.Shutdown(SocketShutdown.Both); handler.Close(); } catch (System.Exception ex) { Console.WriteLine(ex.ToString()); } } public class StateObject { public Socket m_CurSocket = null; public const int m_BufferSize = 1024; public byte[] m_Buffer = new byte[m_BufferSize]; public StringBuilder m_StringBuilder = new StringBuilder(); }}
客户端代码
using UnityEngine;using UnityEngine.UI;using System.Collections;using System.Collections.Generic;using System;using System.Net;using System.Net.Sockets;using System.Text;using System.IO;using System.Runtime.Serialization.Formatters.Binary;using System.Runtime.Serialization;public class Test : MonoBehaviour{ /// <summary> /// 连接到服务器 /// </summary> public void AsynConnect() { //端口及IP IPEndPoint ipe = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 10068); //创建套接字 Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //开始连接到服务器 client.BeginConnect(ipe, asyncResult => { client.EndConnect(asyncResult); //向服务器发送消息 DataMsg msg = new DataMsg(); msg.indexPos = 5; msg.name = "宏宇"; msg.sex = 1; List<string> otherPerList = new List<string>(); otherPerList.Add("小鸭"); otherPerList.Add("斗鸡"); otherPerList.Add("斗鸟"); msg.otherPerList.AddRange(otherPerList); //AsynSend(client, msg); AsynSend(client, "你好我是客户端"); //AsynSend(client, "第一条消息"); //AsynSend(client, "第二条消息"); //接受消息 AsynRecive(client); }, null); } /// <summary> /// 发送消息 /// </summary> /// <param name="socket"></param> /// <param name="message"></param> public void AsynSend(Socket socket, string message) { if (socket == null || message == string.Empty) return; //编码 byte[] data = Encoding.UTF8.GetBytes(message); try { socket.BeginSend(data, 0, data.Length, SocketFlags.None, asyncResult => { //完成发送消息 int length = socket.EndSend(asyncResult); Debug.Log(string.Format("客户端发送消息:{0}", message)); }, null); } catch (Exception ex) { Debug.Log(string.Format("异常信息:{0}", ex.Message)); } } public void AsynSend(Socket socket, DataMsg msgData) { if (socket == null || msgData == null) { return; } Debug.Log(msgData); MemoryStream mStream = new MemoryStream(); //BinaryFormatter bFormatter = new BinaryFormatter(); BinaryFormatter iFormatter = new BinaryFormatter(); //bFormatter.Serialize(mStream, msgData); //bFormatter.Serialize(mStream, "fff"); iFormatter.Serialize(mStream, msgData); mStream.Flush(); byte[] buffer = new byte[1024]; mStream.Position = 0; while (mStream.Read(buffer, 0, buffer.Length) > 0) { socket.Send(buffer); } socket.Close(); Debug.Log("数据发送完毕"); } /// <summary> /// 接收消息 /// </summary> /// <param name="socket"></param> public void AsynRecive(Socket socket) { byte[] data = new byte[1024]; try { //开始接收数据 socket.BeginReceive(data, 0, data.Length, SocketFlags.None, asyncResult => { int length = socket.EndReceive(asyncResult); Debug.Log(string.Format("收到服务器消息:{0}", Encoding.UTF8.GetString(data))); //AsynRecive(socket); }, null); } catch (Exception ex) { Debug.Log(string.Format("异常信息:", ex.Message)); } } void Awake() { gameObject.GetComponent<Button>().onClick.AddListener(delegate() { OnClickEvent(gameObject); }); } void OnClickEvent(GameObject target) { Debug.Log("Click" + target.name); AsynConnect(); }}[Serializable]public class DataMsg{ public int indexPos; public int sex; public string name; public List<string> otherPerList; public DataMsg() { indexPos = 0; sex = 0; name = string.Empty; otherPerList = new List<string>(); }}
大家可能也注意到了我这里的客户端,留有传序列化的数据的方法,没错,本次实验只做传输数据,字符串简单的数据,后面会涉及多终端对一个服务器时的数据传输,等等,一直研究下去
如果有错误的地方,请指点,比较晚了,不好的下次再更新
1 0
- Socket 基础&实例(上)
- Android Socket 基础 & 实例
- Linux下socket基础实例
- Linux Socket 基础实例 (C语言版)-转
- c#中Socket 编程基础实例
- socket编程基础4(实例分析)
- Socket编程基础-使用实例源码
- 续实例解析SOCKET编程模型之异步通信篇(上)
- 续实例解析SOCKET编程模型之异步通信篇(上)
- ESC/POS指令集在Android设备上使用实例(通过socket)
- socket编程实例(源码)
- socket编程实例(源码)
- Socket(上传文件)实例
- Android Socket实例(2)
- Android socket 实例(1)
- Java Socket编程(二)Socket基础
- Java socket 入门编程实例-Java基础-Java-编程开发
- Socket通信编程基础__实例一__server端
- 类的属性、对象的私有字段与主构造器、私有构造器、重载构造器
- 控件的外观代理对象以及+(void)initialize方法
- 【Nginx入门系列】第五章 tomcat在linux下的安装和集群预部署
- POJ--3253 Fence Repair
- InfluxDB权限管理
- Socket 基础&实例(上)
- 【Nginx入门系列】第六章 Nginx+tomcat集群负载均衡部署
- swift基本语法(总结提炼版)之005 Swift之 switch循环
- 最近读书笔记
- [c++]类的构造函数
- HierarchyViewer结合merge标签优化布局结构
- BZOJ 3750
- CSS3 弹性布局弹性流(flex-flow)属性详解和实例
- swift基本语法(总结提炼版)之006 Swift之 while循环