c# TCP程序设计

一、网络协议

1、TCP协议

(1)TCP:传输控制协议

(2)是一种固定连接为基础的协议,可以提供两台计算机间的可靠数据传输。

(3)TCP可以保证从一端将数据传送至另一端,数据能够实时的送达,而且送达的数据排列顺序和送出时的顺序相同。

(4)面向连接的、可靠的、基于字节流的传输通信协议。

TCP通信就像两个人电话通话,必须先播对方电话,等双方接通后,才能对话,是点对点的连接。

2、UDP协议

(1)UDP是连接通信协议,不可靠的数据传输,当能够向若干个目标发送数据,接收发自若干个源的数据。

(2)UDP以独立发送数据包的方式进行。

UDP协议像是村里的广播大喇叭,有的人能听见有的人听不见,到底都有谁听到了,广播的人也不清楚。

3、对比

协议 TCP UDP
  传输可靠,反馈数据是否送达 不可靠,无任何反馈
  需要创建连接请求,连接成功后发数据,效率低 不创建连接请求,直接发送数据,效率高

4、IP地址

特殊ip:127.0.0.1   不进行网络传输,立即返回本地。

c# ip地址封装:

(1)Dns类:是一个静态类,它从Internet域名系统中检索关于特定主机的信息。

(2)IPAdress类:包含计算机在IP网络上的地址,主要用来提供网络协议地址。

(3)IPHostEntry类:为Internet主机信息提供容器类。

三、端口及套接字

1、端口:并非真实的物理存在,而是一个假想的连接装置。

端口一般规定在0-65535之间,0-1023之间的端口号通常用于一些比较知名的网络服务和应用,普通的网路程序应该使用1024以上的端口号,以避免该端口号被另一个应用或系统服务所用。

2、套接字(socket):用于将程序和网络连接起来,套接字是一个假想的连接装置。

四、C#  网络连接类

(1)Socket类:为网络通信提供了一套丰富的方法和属性,主要用于管理连接,实现Berkeley通信端套接字连接,同时还提供了绑定、网络连接端点及数据传输数据所需要的各种方法,提供处理端点连接传输等细节所需要的功能。

(2)TCPClient类:通过网络连接、发送和接收流数据。

(3)TCPListener类:侦听和接收传入的连接请求。

(4)UDPClient类:发送和接收无连接UDP数据报。

一般情况下不需要直接使用Socket类,而是直接使用进一步封装后TcpListener类、TcpClient类以及UdpClient类来实现。这主要是因为使用Socket编写程序比较麻烦。

1、套接字:

(1)类型:流套接字、数据报套接字和原始套接字。流套接字用来实现面向连接的Tcp通信,数据报套接字用来面向无连接的UDP通信,原始套接字实现IP数据包通信。

(2)面向连接的套接字之间的连接过程:

服务器监听、客户端请求、连接确认。

服务器监听:是指服务器套接字并不定位具体的客户端套接字,而是处于等待连接状态,实时检测网络状态。

客户端请求:是指客户端的套接字提出连接请求,要连接的目标是服务器的套接字,为此客户端套接字必须先描述它要连接的服务器套接字,指出服务器套接字的地址和端口,然后再向服务器套接字提出连接请求。

连接确认:指当服务器套接字监听到客户端套接字的连接请求时,它就响应客户端套接字的请求,把服务器套接字的信息发给客户端,一旦客户端接收到这个信息,连接建立。服务器套机字继续监听其它客户端的连接请求。

2、实现过程

(1)建立连接

服务端:

//网络连接
private void connectButton_Click(object sender, EventArgs e)
{
    IPAddress ipAddress=Dns.GetHostAddress("")[0];//获取本地IP地址   
    porttextBox.Text = "8888";//定义端口号
    point = new IPEndPoint(ipAddress,Int32.Parse(porttextBox.Text));//获取ip地址和端口号   
    socket = new Socket(AddressFamily.InterNetwork, SocketType.StreamProtocolType.Tcp);//创建一个本地套接字对象
    socket.Bind(point);//套接字绑定到用于TCP通信的本地IP地址和端口上
    socket.Listen(50);//等待客户端发出连接尝试
    //Listen方法自动的将客户连接请求放到请求队列中,参数指出系统等待用户程序服务排列队的连接数,超过客户端连接数的任何客户都不能与服务器进行通信
//建立接收客户端的连接请求的线程
    Thread thread = new Thread(new ThreadStart(ProcessAccept));
    thread.Start();
    statelabel.Text = "online! monitoring";
    connectButton.Text = "已连接";
}

//接收客户端连接请求
 private void ProcessAccept()
        {
            while (flag)
            {
                try
                {
                    Socket sk = socket.Accept();//程序执行到Accept方法时会被阻塞,直到接收到客户端的连接请求,才执行下一句
                    Work_Process wkp = new Work_Process();
                    wkp.f = this;
                    wkp.acceptedSocket = sk;
                    array1[index_socket] = sk;
                    index_socket++;

                    Thread thread = new Thread(new ThreadStart(wkp.Proccess));
                    thread.Start();
                }
                catch (Exception ey)
                {
                    MessageBox.Show(ey.Message);
                }
            }
        }

   class Work_Process
        {
            public Socket acceptedSocket;
            public Form1 f;
            public void Proccess()
            {
                if (acceptedSocket.Connected)
                {
                    while (true)
                    {
                        byte[] receiveByte = new byte[64];
                        //int t=acceptedSocket.Receive(receiveByte, receiveByte.Length, 0);
                        acceptedSocket.Receive(receiveByte);
                        string strInfo = byteToHexStr(receiveByte);
                        f.UpdateTextBox(receiveByte);
                    }
                }
            }

客户端:

客户端利用Socket的Connect方法向编程主机的端点发起连接请求,并将自身绑定到系统自动分配的端点。

IPAddress remoteHost = IPAddress.Parse("192.168.0.1");
IPEndPoint iep = new IPEndPoint(remoteHost,80);
Socket localSocket= new Socket(AddressFamily.InterNetwork, SocketType.StreamProtocolType.Tcp);//创建一个本地套接字对象
localSocket.Connect(iep);//客户端和服务器建立连接之前,系统不会执行Connect语句下面的语句,而处于阻塞状态,直到连接成功或出现异常为止

(2)发送和接收消息

服务端:当服务端接收到客户端的连接请求成功时,Accept方法将返回包含该客户端IP地址及端口号信息的套接字,服务器可以用该套接字与客户端通信。

Socket clientSocket localSocket.Accept();//等待客户端的连接请求
//建立连接后,利用Send方法向客户端发送信息

 clientSocke.Send(Endcoding.ASCII.GetBytes("server send Hello"));

//接收客户端信息

byte [] myresult = new Byte [1024];

int receiveNum = clientSocket.Receive(myresult);

客户端:客户端可直接使用本地套接字的send方法向服务器发送信息,利用Receive方法接收服务器信息。

localSocket.Connect(iep);
//建立连接成功后,向服务器发送消息
String sendMessage ="hello";
localSocket.Send(Encoding.ASCII.GeBytes(sendMessage));
console.WrieLine("向服务器发送消息:{0}",sendMessage);

//接收服务端信息
byte[] result =new Byte[1024];
localSocket.Receive(result);

(3) 关闭连接

localSocket.Shutdown(SocketShutdown.Both);
localSocket.Close();

猜你喜欢

转载自blog.csdn.net/kenjianqi1647/article/details/82859196