socket套接字

进程通信机制。用来描述IP地址和端口,是一个通信链的句柄。

两种类型:

流式:一种面向连接的socket,针对面向连接的tcp服务应用,安全,但效率低。

数据报式:一种无连接的socket,对应于无连接的udp服务应用。不安全(丢失),顺序混乱,在接收端要分析重排及要求重发,但效率高。

服务端与客户端通讯过程

服务端

  申请一个socket--绑定到一个ip地址和端口--开启监听,等待接收和连接

客户端

  申请一个socket--连接服务器(指明ip地址和端口号)

服务端接到连接请求后产生一个新的socket与客户端建立连接并进行通讯。原监听socket继续监听。

注意:

至少要定义一个要连接的远程主机的ip和端口号。

端口号必须在1到65535之间,最好在1024以后。

要连接的远程主机必须正在监听指定端口。

一个socket一次只能连接一台主机。

socket关闭后无法再次使用。

每个socket对象只能一台远程主机连接。如果想连接到多台远程主机,必须创建多个socket对象。

 

//简单服务器与客户端通信实现

//服务端

//在构造函数里初始化完组件后取消下跨线程检查。

Control.CheckForIllegalCrossThreadCalls=false;

//定义一个全局的socket

Socket sockServer;

//创建一个字典集合保存与客户端通信的套接字 界面上放置一个listview显示当前连接的客户端ip终结点 listViewOnline

Dictionary<string,Socket> dictSocket=new Dictionary<string,Socket>();

 

socketServer=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.TCP);

IPAddress address=IPAddress.Parse(127.0.0.1);

IPEndPoint endPoint=new IPEndPoint(address,Convert.ToInt32(8001));

//监听套接字绑定到端口上

socketServer.Bind(endPoint);

//设置监听队列的最大长度

socketServer.Listen(10);

//服务已启动。。。

//可以开启一个线程监听并接收客户端连接请求

Thread threadWatch=new Thread(WatchConnet);

threadWatch.IsBackground=true;

threadWatch.Name="watchThread";

threadWatch.Start();

 

//WatchConnect监听连接请求

bool isWatch=true;

void WatchConnect()

{

try

{

while(isWatch)

{

//监听并接收客户端连接请求,如果有连接过来则返回一个负责通信的套接字

Socket sokMsg=sockServer.Accept();

//获取客户端终结点

string clientKey=sokMsg.RemoteEndPoint.ToString();

//添加到listview中

listViewOnline.Items.Add(clientKey,clientKey,"");

//添加到集合中

dictSocket.Add(clientKey,sokMsg);

//有客户端连接

//可以创建一个通信线程

Thread threadRecMsg=new Thread(WatchMsg);

threadRecMsg.IsBackground=true;

threadRecMsg.Name="threadRecMsg";

threadRecMsg.Start(sokMsg);

}

}

catch(Exception ex){}

}

 

//接收客户端发来的消息

void WatchMsg(object sok)

{

Socket sokMsg=null;

try

{

while(isWatch)

{

sokMsg= sok as Socket;

byte[] arrMsg=new byte[1024*1024];

int length=sokMsg.Receive(arrMsg);

string msg=Encoding.UTF8.GetString(arrMsg,0,arrMsg.Length);

//客户端发送的内容:msg

}

}

catch(Exception ex){}

}

 

//向指定客户端发送消息

if(listViewOnline.SelectedItems.Count>0)

{

string clientKey=listViewOnline.SelectedItems[0].Text;

//判断通信套接字是否包含此客户端的网络节点

if(dictSocket.ContainsKey(clientKey))

{

string strMsg="发送给客户端"+clientKey+"的消息";

byte[] arrMsg=Encoding.UTF8.GetBytes(strMsg);

//根据节点找到字典中对应的通信套接字对象,并调用send方法向客户端发送消息。

dictSocket[clientKey].Send(arrMsg);

}

}

 

//客户端

//创建一个全局socket

Socket sokClient;

 

sokClient=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

IPEndPoint endpoint=new IPEndPoint(IPAddress.Parse(127.0.0.1),int.Parse(8001));

try

{

sokClient.Connect(endpoint);

//可以创建一个线程与服务端通信

Thread threadClient=new Thread(WatchMsgFromServer);

threadClient.IsBackground=true;

threadClient.Name="WatchMsgFromServer";

threadClient.Start();

}

catch(Exception ex){}

 

//监听通信

void WatchMsgFromServer()

{

try

{

while(true)

{

byte[] arrMsg=new byte[1024*1024];

int realLength=sokClient.Receive(arrMsg);

string strMsg=Encoding.UTF8.GetString(arrMsg,0,realLength);

//服务器发送的内容:strMsg

}

}

catch(Exception ex){}

}

//给服务端发送消息

string msgSend=“给服务端发送的消息”;

byte[] arrMsg=Encoding.UTF8.GetBytes(msgSend);

sokClient.Send(arrMsg);

 

posted @ 2017-05-08 15:21  jechsky  阅读(199)  评论(0编辑  收藏  举报