您的位置:首页 > 编程语言 > C#

C#编程之Socket套接字编程

2017-07-05 16:43 309 查看

Socket套接字

一.什么是Socket?

网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。

用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。



链接过程:

根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。

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

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

(3)连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

二.Socket套接字的数据结构



套接字类型:

1.流式套接字(TCP);

2.数据报套接字(UDP);

3.原始套接字(IP):用于直接访问协议的较低底层;

套接字类型区别:



创建流式套接字:

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




创建数据报套接字:

Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);


三.代码示例

1.Server端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace Socket_Server
{
class Program
{
private static byte[] result = new byte[1024];      //创建字节数组
private static int myPort = 8885;                   //端口
static Socket serverSocket;
static void Main(string[] args)
{
//服务器IP地址
IPAddress ip = IPAddress.Parse("127.0.0.1");    //构造IP
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);     //指定套接字类型:TCP模式
//AddressFamily:网络类型  SocketType:套接字类型 ProtocolType:使用的网络协议
serverSocket.Bind(new IPEndPoint(ip, myPort));  //绑定IP地址:端口
serverSocket.Listen(10);                        //设定最多10个排队链接请求
Console.WriteLine("启动监听{0}成功!", serverSocket.LocalEndPoint.ToString());
//通过Client_Socket发送数据
Thread myThread = new Thread(ListenClientConnect);  //创建一个新的线程,并用于监听客户端链接
myThread.Start();
Console.ReadLine();
}
//监听客户端链接
private static void ListenClientConnect()
{
while (true)
{
Socket clientSocket = serverSocket.Accept();    //同意链接
clientSocket.Send(Encoding.ASCII.GetBytes("Server Say Hello"));     //字符串转换为字节数组,并发送
Thread receiverThread = new Thread(ReceiveMessage);
receiverThread.Start(clientSocket);
}
}
//接收消息
private static void ReceiveMessage(object clientSocket)
{
Socket myClientSocket = (Socket)clientSocket;
while (true)
{
try
{
//通过clientSocket接收数据
int receiveNumber = myClientSocket.Receive(result);     //接收缓冲数组,并读取数组内容

Console.WriteLine("接收客户端{0}消息{1}.", myClientSocket.RemoteEndPoint.ToString(), Encoding.ASCII.GetString(result, 0, receiveNumber));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
myClientSocket.Shutdown(SocketShutdown.Both);
myClientSocket.Close();
break;
}
}
}
}
}


Client端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace Socket_Client
{
class Program
{
private static byte[] result = new byte[1024];  //创建字节数组
static void Main(string[] args)
{
//设定服务器IP地址
IPAddress ip = IPAddress.Parse("127.0.0.1");
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
clientSocket.Connect(new IPEndPoint(ip, 8885));     //配置服务器IP:端口
Console.WriteLine("连接服务器成功!");
}
catch
{
Console.WriteLine("连接服务器失败,请按回车键退出!");
return;
}
//通过clientSocket接收数据
int receiveLength = clientSocket.Receive(result);
Console.WriteLine("接受服务器消息:{0}.",Encoding.ASCII.GetString(result, 0, receiveLength));
//通过clientSocket发送数据
for (int i = 0; i < 10; i++)
{
try
{
Thread.Sleep(1000);     //线程休眠1000毫秒,即等待一秒钟
string sendMessage = "Client send message! " + DateTime.Now;
clientSocket.Send(Encoding.ASCII.GetBytes(sendMessage));    //创建字节,发送缓冲数组,并向数组内填充发送内容.实现字符串与字节数组转换
Console.WriteLine("向服务器发送消息:{0}.", sendMessage);
}
catch
{
clientSocket.Shutdown(SocketShutdown.Both);     //关闭Socket
clientSocket.Close();
break;
}
}
Console.WriteLine("发送完毕,按回车键退出.");
Console.ReadKey();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: