一.Socket简介
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。
建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。
Socket的英文原义是"孔"或"插座"。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原义那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。客户软件将插头插到不同编号的插座,就可以得到不同的服务。
图示
二.基于Socket开发TCP服务器简要步骤
第一步:调用socket()函数创建一个用于通信的套接字
第二步:给已经创建的套接字绑定一个端口号,这一般通过设置网络套接口地址和调用bind()函数实现
第三步:调用listen()函数使套接字成为一个监听套接字
第四步:调用accept()函数来接受客户端的连接,这时就可以和客户端通信了
第五步:处理客户端的连接请求
第六步:终止连接
图示
三.主体(部分)代码贴
private void btn_StartService_Click(object sender, EventArgs e)
{
//参数含义:IPV4,流式套接字,TCP协议
//第一步:调用socket()函数创建一个用于通信的套接字
socketServer = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);//第三种重载方式
//绑定ip地址 端口号
//第二步:给已经创建的套接字绑定一个端口号,一般通过设置网络套接字地址和调用Bind()函数来实现
IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(this.txt_IP.Text), int.Parse(this.txt_Port.Text));//声明
try
{
socketServer.Bind(ipe);//绑定
}
catch (Exception ex)
{
AddLog(2, "服务器开启失败"+ex.Message);
return;
}
//第三步:调用listen()函数使套接字成为一个监听套接字
socketServer.Listen(10);//设置监听队列数
//创建一个监听线程
Task.Run(new Action(() =>
{
checkListening();
}));
AddLog(0, "服务器开启成功");
this.btn_StartService.Enabled = false;
}
///
/// 监听程序
///
private void checkListening()
{
while (true)
{
//第四步:调用accept()函数来接受客户端的连接,这时就可以和客户端通信了
//循环 内是防止每次只能连接一个
Socket socketClinent= socketServer.Accept();
string client = socketClinent.RemoteEndPoint.ToString();
AddLog(0, client + "上线了");
CurrentClientList.Add(client, socketClinent);
UpdateOnline(client, true);//添加到在线列表
Task.Run(new Action(() =>
{
ReceiveMessage(socketClinent);
}));
}
}
///
/// 接收客户端信息消息数据
///
///
private void ReceiveMessage(Socket socketClinent)
{
while (true)
{
//创建缓冲区
byte[] buffer = new byte[1024 * 1024 * 10];
int length = -1;
string client = socketClinent.RemoteEndPoint.ToString();
//第五步:处理客户端请求,这里会传入一个字节数组,创建一个字节数组来接收
try
{
length = socketClinent.Receive(buffer);
}
catch (Exception)
{
UpdateOnline(client, false);
AddLog(0, client + "下线了");
CurrentClientList.Remove(client);
break;
}
if (length>0)
{
//处理
string msg = Encoding.Default.GetString(buffer, 0, length);//来自远程客户端传送的数据
AddLog(0, client + ":" + msg);
}
else
{
UpdateOnline(client, false);
AddLog(0, client+"下线了");
CurrentClientList.Remove(client);
break;
}
}
}
四.连接测试
随笔记