C#Socket开发TCP详解(二)

C#Socket开发TCP详解(二)–面向连接的套接字编程

简介:

SOCKET(套件字)是支持TCP/IP 网络通信的基本操作单元。System.Net.Sockets 命名空间提供了TcpClient类、TcpListener类和UdpClient类。这些类封装了不同传输协议建立连接、操作方法的细节。
套接字有3中不同的类型:
流套接字:面向连接的TCP通信。
数据报套接字:实现无连接的UDP通信。
原始套接字:实现IP数据报通信。
socket类的构造函数:
public Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType);
对应参数的意义:
AddressFamily:网络类型,如IP版本4、IP版本6等;
SocketType :套间字类型,如流套接字,数据报套接字等;
ProtocolType :传输协议类型,如TCP、UDP等。

面向连接的套接字

在面向连接的套接字中,使用TCP来建立两个IP地址端点之间的会话。一旦设备建立的连接,就可以在设备之间进行可靠的数据传输。

为了建立面向连接的套接字,服务器和客户端需要分别进行编程。
在这里插入图片描述

1、建立连接

连接过程需要3个过程:服务器监听、客户端请求、连接确认。

(1)服务器编程。
在服务器中,首先创建一个本地套接字对象。如下:
//使用IPv4地址,流式socket方式,tcp协议传递数据

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

然后,将套接字绑定到本地IP和端口上。Bind方法用于完成绑定工作。如下:

   //ip地址
      IPAddress ip = IPAddress.Parse(txtIP.Text);
   // IPAddress ip = IPAddress.Any;
     //端口号
   IPEndPoint point=new IPEndPoint(ip,int.Parse(txtPort.Text));
  socket.Bind(point);

将套接字与端口绑定之后,就用Listen方法等待客户端发出的尝试连接。如下:

socket.Listen(10);

Listen方法,自动将客户连接请求放到请求队列中,参数指出系统等待用户程序服务排队的连接数,超过连接数的任何客户都不能与服务器进行通信。

在Listen方法执行之后,服务器已经做好了接收任何连接的准备。这时,可用Accept方法从请求队列中获取连接。如下:
socket.Accept();

程序执行到Accept方法时会阻塞,直到收到客户端的连接请求,才继续执行下一条语句。服务器一旦接受了该客户端的连接请求,Accept方法立即返回一个与该客户端通信的信的套接字,该套接字中既包含了本机的IP地址和端口号,也包含了客户端的IP地址和端口号,然后利用此套接字与客户端进行通信了。

在实际应用场合中,为了能够与多个客户端通信,可以用一个线程监听客户端的连接请求,在该线程中循环调用Accept方法接收新的客户端连接。如下:


 Thread th = new Thread(Listen);
 th.IsBackground = true;
 th.Start(socketWatch);

 Socket socketSend;
Dictionary<string, Socket> diclist = new Dictionary<string, Socket>();
 /// <summary>
 /// 等待客户端的连接,并且创建与之通信用的Socket
 /// </summary>
 /// <param name="obj"></param>
 private void Listen(object obj)
 {
     Socket socketWatch = obj as Socket;
     while (true)
     {
         try
         {
             //等待客户端的连接,并且创建一个用于通信的Socket
             socketSend = socketWatch.Accept();
             //将客户端socket存到集合中
             diclist.Add(socketSend.RemoteEndPoint.ToString(), socketSend);
             //将客户端ip 存到下拉列表中
             comboBox1.Items.Add(socketSend.RemoteEndPoint.ToString());
             ShowBox(socketSend.RemoteEndPoint.ToString() + ":连接成功");
             //
             Thread th = new Thread(Receive);
             th.IsBackground = true;
             th.Start(socketSend);
         }
         catch 
         {
             
         }
     }
 }

(2)客户端编程。
客户端利用Socket的connect方法向远程主机的断点发起连接请求。并将自身绑定到系统自动分配的端电上。如下:

IPAddress ip = IPAddress.Parse("192.168.10.3");
IPEndPoint point = new IPEndPoint(ip, int.Parse("9008"));
localSocket= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
localSocket.Connect(point);

程序运行后,客户端与服务器建立连接之前,系统不会执行connect语句下面的内容,而是处于阻塞状态,知道连接成功或出现异常为止。

2、发送和接收消息

客户端与服务器建立连接,客户端和服务器都可以使用Socket对象的Send和Receive方法进行通信。
(1)服务器端编程
当服务器接收客户端的连接请求成功时,Accept方法将返回包含该客户端IP地址及端口号信息的套接字。服务器可以用该套接字与客户端进行通信。
a.发送消息

Socket clientsocket = socketWatch.Accept();
//建立连接后,用Send方法向客户端发送消息
clientsocket.Send(Encoding.ASCII.GetBytes("server send Hello"));


b、接收消息

//客户端连接成功后,服务器端该接受客户端发来的额消息
byte[] buffer = new byte[1024 * 1024 * 2];
//时间接收到的有效字节数
int r = socketSend.Receive(buffer);
if (r == 0)
{
break;
}
string str = Encoding.UTF8.GetString(buffer, 0, r);

ShowBox(socketSend.RemoteEndPoint + ":" + str);  //输出打印消息

(2)客户端编程。
客户端可直接使用本地套接字的Send 方法向服务器发送消息,利用Receive方法接收服务器信息,例如:
a.向服务器发送消息

localSocket.Connect(point);
string str = textBox4.Text.Trim();  //添加文本
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
localSocket.Send(buffer); //发送

b.接收服务器发来的消息

byte[] buffer = new byte[1024 * 1024 * 2];
 localSocket.Receive(buffer);
 Console.WriteLine("接收服务器消息:{0}",Encoding.ASCII.GetString(buffer))

3、关闭连接

注意通信完成后,必须先用Shutdown方法停止会话,然后关闭Socket实例。

localSocket.Shutdown(SocketShutdown.Both); //在套接字上既停止发送也停止接收。
localSocket.Close();

参考资料:《C#网络编程第2版》马骏主编 人民邮电出版社

示例程序及代码:
客户端界面:
在这里插入图片描述
服务端界面
在这里插入图片描述
程序地址:https://download.csdn.net/download/qq_21291397/12983392

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值