Socket

 Socket包括Ip地址和端口号两部分,程序通过Socket来通信,Socket相当于操作系统的一个组件。
 Socket作为进程之间通信机制,通常也称作”套接字”,用于描述IP地址和端口号,是一个通信链的句柄。
 注意:Socket不仅可以在两台电脑之间通信,还可以在同一台电脑上的两个程序间通信。
Socket分类
Socket主要有两种类型:
流式Socket
	是一种面向连接的Socket,针对于面向连接的TCP服务应用,安全,但是效率低
数据报式Socket
	是一种无连接的Socket,对应于无连接的UDP服务应用,不安全,但效率高
Socket一般应用模式(服务器端和客户端)

服务器端的Socket(至少需要两个)

01.一个负责接收客户端连接请求(但不负责与客户端通信)

02.每成功接收到客户端的连接便在服务器端产生一个对应的复杂通信的Socket

	021.在接收到客户端连接时创建
	
	022为每个连接成功的客户端请求在服务器端都创建一个对应的Socket(负责和客户端通信)
Socket的通讯过程

客户端:

01,申请一个socket

02,连接服务器(指明IP地址和端口号)
服务器端接收到连接请求后,产生一个新的socket(端口大于1024)与客户端建立连接并进行通信,原监听socket继续监听。
注意:负责通信的Socket不能无限创建,创建的数量和操作系统有关。

服务器端:

01,申请一个socket

02,绑定到一个IP地址和一个端口上

03,开启侦听,等待接收连接



Socket常用类和方法

相关类:

IPAddress:包含了一个IP地址

IPEndPoint:包含了一对IP地址和端口号

方法:

Socket():创建一个Socket

Bind():绑定一个本地的IP和端口号(IPEndPoint)

Listen():让Socket侦听传入的连接吃那个病,并指定侦听队列容量

Connect():初始化与另一个Socket的连接

Accept():接收连接并返回一个新的Socket

Send():输出数据到Socket

Receive():从Socket中读取数据

Close():关闭Socket,销毁连接




C#服务端截图

在这里插入图片描述
部分核心代码:

	
	//创建socket
	//ip地址
    IPAddress ip = IPAddress.Parse(ipText.Text);
    //端口号
    IPEndPoint point = new IPEndPoint(ip, int.Parse(portText.Text));
    //创建监听用的Socket,流数据和TCP协议.
    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    try
    {
        socket.Bind(point); //绑定监听的端口.
        socket.Listen(10);  //监听队列
        Thread thread = new Thread(AcceptInfo);
        thread.Start(socket);   //不加socket参数,无法连接.
    }catch(Exception ex)
    {
     	//报错
    }
	void AcceptInfo(object o)
        {
            Socket socket = o as Socket;
            while (true)
            {
                //通信用socket
                try
                {
                    //创建通信的Socket
                    Socket tSocket = socket.Accept();   //等待连接.
                    string point = tSocket.RemoteEndPoint.ToString();   //端口号
                    clientIP = point;   //包含ip+端口,即客户端的ip+端口
                    //显示连接成功.
                    showMsg(point + " : 连接成功!");
                    //此时将clientIP发送给客户端,
                    byte[] buffer = Encoding.UTF8.GetBytes(clientIP); //发给客户端,客户端ip和端口
                    tSocket.Send(buffer);   //发送接收信息给客户端  
                    //接收消息.
                    Thread th = new Thread(receiveMsg);
                    th.Start(tSocket);
                }catch(Exception ex)
                {
                    //报错
                }
            }
        }
    //接收信息
    //定义byte数组存放客户端接收过来的数据
   byte[] buffer = new byte[1024 * 1024];
   int len = client.Receive(buffer);//字节转字符串.
   string words = Encoding.UTF8.GetString(buffer, 0, len);
   //client.RemoteEndPoint.ToString() == clientIP  true
   showMsg(client.RemoteEndPoint.ToString() + ":" + words);	//显示在控件上的.
   private void Btnsend_Click(object sender, EventArgs e)
   {
       try
       {
           showMsg(ipText.Text+":"+txtMsg.Text);
           byte[] buffer = Encoding.UTF8.GetBytes(ipText.Text+" : " + txtMsg.Text); //发给客户端,和服务器ip和文本
           dic[clientIP].Send(buffer);   //支持多客户端连接.
           //client.Send(buffer);
       }catch(Exception ex)
       {
           showMsg(ex.Message);
       }
   }
   void showMsg(string msg)
   {
       System.DateTime currentTime = new System.DateTime();//创建DateTime对象
       currentTime = System.DateTime.Now;//对象当前时间.
       textlog.AppendText(currentTime.ToString() + "\r\n"); //发送时间
       textlog.AppendText(msg + "\r\n");
       textlog.AppendText("\r\n"); //换行,注目.
   }



C#客户端截图

在这里插入图片描述
部分核心代码:

	socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    IPAddress ip = IPAddress.Parse(this.textIP.Text.Trim());    //获取ip地址.
    socketSend.Connect(ip, Convert.ToInt32(this.textPort.Text.Trim()));	//建立连接.
    showMsg("连接成功");
    showMsg("服务器" + socketSend.RemoteEndPoint.ToString());
    showMsg("客户端" + socketSend.LocalEndPoint.ToString());
	Thread th = new Thread(ReceiveMsg);	//写法类似Runnable.
    th.Start();	//开启线程
	private void ReceiveMsg()
	 {
	 	while (true)
	    {
           try
           {
               byte[] buffer = new byte[1024 * 1024];
               int len = socketSend.Receive(buffer);   //获取长度
               string s = Encoding.UTF8.GetString(buffer, 0, len);	//从buffer中获得字符串.
               //将信息显示在textArea中.
               showMsg(socketSend.RemoteEndPoint.ToString() + ":" + s);
           }catch(Exception ex)
           {
               showMsg(ex.Message);
               break;
           }
      }
   }
   //发送消息
   //发送消息.
   showMsg(txtMsg.Text);
   byte[] buffer = Encoding.UTF8.GetBytes(txtMsg.Text);
   socketSend.Send(buffer);	//发送消息,以流的形式.
   void showMsg(string msg)
   {
        textInfo.AppendText(msg + "\r\n");	//textInfo为textbox
    }



总结:

1.创建一个线程用来接收从服务端发送来的消息.
2.每当服务器监听到一个新的客户端连接时,创建一个socket来与之对应,即创建一个新的端口号来与客户端保持连接,然后使用字典的形式,将客户端的端口号保存起来,方便下次发送消息.
3.该程序使用流式Socket,数据发送和接收都是以数据流的形式进行。

源码上传到github中
https://github.com/Githubforusc2018/C-socket

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐