C#之Socekt(套接字)通讯(上)

一、Socket编程

1)在网络中计算机之间如何互相找到?什么是IP地址与端口?

TCP/IP(传输控制协议/网际协议)是一组网络通信协议的总成,它规范了网络上的所有通信设备,尤其是一个主机与另一个主机之间的数据交换格式以及传送方式。

IP(Internet Protocol)是Internet网络设备之间传输数据的一种协议,IP地址就是给每个连接在因特网上的主机(或路由器)分配一个在全世界范围内唯一的标识符。

端口(Port)标识某台计算机上的进程

2)TCP(传输控制协议)是TCP/IP体系中面向连接的运输层协议,在网络中提供全双工的和可靠的服务,TCP协议最主要的特点是:

1.是一种基于连接的协议。

2.保证数据准确到达。

3.保证个数据到达的顺序与数据发出的顺序相同。

3)UDP是一个简单的、面向数据的无连接协议,提供了快速但不一定可靠的传输服务。UDP协议最主要的特点是:

1.是基于无连接的协议,没有生成连接的系统延迟,所以速度必TCP更快。

2.支持一对一连接,也支持一对多连接,可以使用广播的方式多地址发送。

3.与TCP的报头比是8:20,这使得UDP消耗的网络宽带更少。

4.协议传输的数据有消息边界,而TCP协议没有消息边界。

4)套接字(Socket)

套接字是支持TCP/IP协议的网络通信的基本操作单元。可以将套接字看作不同主机间的进程进行双向通信的端点,它构成了单个主机内及整个网络间的编程界面。

5)Socket类的构造实例

Socket localSocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
SocketTypeProtocolType说明
DgramUdp无连接通信
StreamTcp面向连接的通信
RawIcmpInternet控制报文协议
RawRaw简单IP包协议

二、面向连接的Socket

1)面向连接的(即:流式):安全但是效率低。在发送数据前,会先经历TCP的三次握手,建立连接,发送完毕会发生回执。全过程会一直保持连接状态,比较消耗资源。

2)面向连接的套接字中,使用TCP协议来建立两个IP地址端点之间的绘画。一旦建立了这种连接,就可以在设备之间可靠的传输数据。为了建立面向连接的套接字,服务器和客户端必须分别进行编程。、

3)面向连接通信步骤

服务器端:1.申请一个Socket 2.绑定到一个IP地址和端口上 3.开启监听,等待接收连接

客户端:1.申请体格Socket 2.连接服务器,且制定IP和端口号

特别注意:服务器端接到连接请求后,产生一个新的Socket(端口大于1024)与客户端建立连接并进行通讯,原来的监听Socket,继续监听

 

//学习Socket通讯技术
//服务器端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//需要引入的命名空间
using System.Net.Socket;							//Socket命名空间
using System.Net;									//网络命名空间
using System.Threading;								//多线程命名空间
public class Server{
    private Socket _SocketServer;					//服务器监听Socket
    private bool _IsListenContecion;				//是否在监听(目的是方便退出)
    public Server(){
        //定义网络终结点(封装IP与端口),127.0.0.1表示本机,端口尽量大于1024
        IPEndPoint endPoint=new IPEndPoint(IPAddress.Parse("127.0.0.1"),1050);
        //实例化Socket(监听)
        _SocketServer=new Socket(AddressFamily.InterNetWork,SocketType.Stream,ProtocolType.Tcp);
        //服务器端绑定地址
        _SocketServer.Bind(endPoint);
        //开始监听
        _SocketServer.Listen(10);//10表示监听队列的最大长度,可以改变
        Console.WriteLine("服务器端已经启动");
        
        try{
            while(_IsListenContecion){
                //Accept()方法,接收客户端的连接
                //这个方法会阻断当前线程的运行,所以需要建立一个单独的线程
                Socket sockMsgServer= _SocketServer.Accept();
                Console.WriteLine("此时有一个客户端连接。。。");
                
                //开启后台线程,进行客户端的会话
                Thread thClientMsg=new Thread(ClientMsg);
                thClientMsg.InBackground=true;		//定义成后台线程
                thClientMsg.Name="thClientMsg";
                thClientMsg.Start(sockMsgServer);
            }
        }catch(Exception){
            
        }
    }
    //服务器端与客户端的通信后台线程
    //sockMsg表示服务器端的会话Socket
    private void ClientMsg(objetc sockMsg){
        Socket socketMsg=sockMsg as Socket;			//通讯Socket
        while(true){
            //准备一个“数据缓存”
            byte[] msgArray=new byte[1024*1024];	//最大长度1M空间
            //接收客户端发来的数据,返回数据真实的长度
            int trueClineMsgLength=socketMsg.Receive(msgArray);
            //byte数组转String
            String strMsg=Encoding.UTF8.GetString(msgArray,0,trueClineMsgLength);
            //显示客户端发来的数据
            Console.WriteLine("客户端发来的数据"+strMsg);
        }
    }
    static void Main(string[] args){
        Server obj=new Server();
    }
}
//客户端,注意:应当新开个项目
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//需要引入的命名空间
using System.Net.Socket;					//Socket命名空间
using System.Net;							//网络命名空间
using System.Threading;						//多线程命名空间
public class Client{
    private Socket _SocketClient;			//通讯Socket
    private IPEndPoint sertEndPoint;		//需要连接的服务器IP与端口信息
    
    public Client(){
        //(服务器端)通讯地址与端口号
        sertEndPoint=new IPEndPoint(IPAddress.Parse("127.0.0.1"),1050);
        //建立客户端的Socket
        _SocketClient=new Socket(AddressFamily.InterNetWork,SocketType.Stream,ProtocolType.Tcp);
        
        try{
            _SocketClient.Connect();
        }catch(Exception){
            
        }
        Console.WriteLine("连接服务器成功");
    }
    //连接服务器
    public void SendMsg(){
        while(true){
            //输入信息
        string strMsg=Console.ReadLine();
        //退出
        if(strMSg=="exit"){
            break;
        }
        //字节转换
        Byte[] byteArray=Encoding.UTF8.GetBytes(strMsg);
        //发送数据
        _SocketClient.Send(byteArray);
        Console.WriteLine("我"+strMsg);
        }
        //关闭连接
        _SocketClient.Shutdown(SocketShutdown.Both);
        //清理连接资源
        _SocketClient、Close();
    }
    static void Main(string[] args){
        Client obj=new Client();
        obj.SendMsg();
    }
}

 

三、无连接的Socket、

1)无连接的(即:数据报文格式):UDP服务,不安全,但效率高。将数据拆成很多分(包),然后发给对方,对方是否收到不予以理睬。采取发生完毕就立即关闭连接的方式,比较省资源。例如:迅雷下载等。(可以“多点”

同时下载)

2)UDP协议使用无连接的Socket,无连接的套接字不需要在网络设备之间发送信息。须用Bind方法绑定到一个本地地址/端口对上。完成绑定之后,该设备就可以利用Scoket接收数据了。由于发送设备没有建立到接收设备地址的连接,所以收发数据均不需要Listen(),Connect()方法。

3)无连接Socket通讯步骤

建立一个Socket

绑定本机的IP和端口作为服务器端

UDP不需要Listen(),accept(),直接使用SendTo()/ReceiveFrom()来执行操作。(和TCP的执行方法有区别,因为UDP不需要建立连接,所以在发送前并不知道对方的IP和端口,因此需要指定一个发送的目标位置才能进行正常的发送和接收)

//接收端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//需要引入的命名空间
using System.Net.Socket;					//Socket命名空间
using System.Net;							//网络命名空间
using System.Threading;						//多线程命名空间
public class Server{
    private Socket _SocketServer;					//Socket
    private bool _IsListenContecion;				//是否在监听(目的是方便退出)
    public Server(){
        //定义网络终结点(封装IP与端口),127.0.0.1表示本机,端口尽量大于1024
        IPEndPoint endPoint=new IPEndPoint(IPAddress.Parse("127.0.0.1"),1050);
        //实例化Socket,协议不同
        _SocketServer=new Socket(AddressFamily.InterNetWork,SocketType.Dgram,ProtocolType.Udp);
        //服务器端绑定地址
        _SocketServer.Bind(endPoint);
        
        EndPoint ep=(EndPoint)endPoint;
        while(true){
            //准备一个“数据缓存”
            byte[] msgArray=new byte[1024*1024];	//最大长度1M空间
            //接收客户端发来的数据,返回数据真实的长度
            int trueClineMsgLength=_SocketServer.ReceiveFrom(msgArray,ref ep);
            //byte数组转String
            String strMsg=Encoding.UTF8.GetString(msgArray,0,trueClineMsgLength);
            //显示客户端发来的数据
            Console.WriteLine("客户端发来的数据"+strMsg);
        }
    }
    
    static void Main(string[] args){
        Server obj=new Server();
    }
}
//发送端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//需要引入的命名空间
using System.Net.Socket;					//Socket命名空间
using System.Net;							//网络命名空间
using System.Threading;						//多线程命名空间
public class Client{
    private Socket _SocketClient;			//通讯Socket
    private IPEndPoint sertEndPoint;		//需要连接的服务器IP与端口信息
    
    public Client(){
        //(服务器端)通讯地址与端口号
        sertEndPoint=new IPEndPoint(IPAddress.Parse("127.0.0.1"),1050);
        //建立客户端的Socket,协议不同
        _SocketClient=new Socket(AddressFamily.InterNetWork,SocketType.Dgram,ProtocolType.Udp);
        
        EndPoint ep=(EndPoint)sertEndPoint;
         while(true){
            //输入信息
        string strMsg=Console.ReadLine();
        //退出
        if(strMSg=="exit"){
            break;
        }
        //字节转换
        Byte[] byteArray=Encoding.UTF8.GetBytes(strMsg);
        //发送数据
        _SocketClient.SendTo(byteArray,ref ep);
        Console.WriteLine("我"+strMsg);
        }
        //关闭连接
        _SocketClient.Shutdown(SocketShutdown.Both);
        //清理连接资源
        _SocketClient、Close();
    }
    static void Main(string[] args){
        Client obj=new Client();
    }
}

 

 

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱卷的小Zang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值