一  Socket简介

  1. Socket翻译过来是套接字,具体含义可自行百度,简言之就是IP:Port的组合,是网络通信的一个窗口,IP就是地址和门牌号(比如长沙市韶山北路81号),Port就是房间号(比如6楼611室)。
  2. Visual Studio(简称VS)中System.Net.Sockets命名空间就是提供Socket网络应用的相关类的,其中Socket类、TcpClient类、TcpServer类、TcpListener类较为常用,是实现Socket网络通信必备的。至于“命名空间”、“类”等术语限于篇幅请自行百度。
  3. 我们常用的SocketTool.exe就是用Socket技术实现的。
  4. Socket之间的通信可以类比生活中打电话的案例。任何用户在通话之前,首先要占有一部电话机,相当于申请一个Socket,同时要知道对方的号码,相当于对方有一个固定的Socket,然后向对方拨号呼叫,相当于发出连接请求。假如对方在场并空闲,拿起 电话话筒,双方就可以进行通话了。双方的通话过程,是一方向电话机发出信号和对方从电话机接收信号的过程,相当于向socket发送数据和从socket接收数据。通话结束后,一方挂起电话机,相当于关闭socket,撤销连接。
  5. Socket不仅可以在两台电脑之间通信,还可以在同一台电脑上的两个程序间通信。

二  Socket一般应用模式

Socket一般应用模式即:客户端、服务器模式

服务器端侦听一般会打开至少两个Socket

01.一个负责接收客户端连接请求(但不负责与客户端通信)
02.每成功接收到客户端的连接便在服务器端产生一个与之对应的通信的Socket,该Socket是在接收到客户端连接时就会创建的,为每个连接成功的客户端请求在服务器端都创建一个对应的Socket(负责和客户端通信)

客户端的Socket

01.必须指定要连接的服务器地址和端口
02.通过创建一个Socket对象来初始化一个到服务器端的TCP连接

下面是一张服务器、客户端Socket通信的原理图

下面我们来看下Socket更具体的通信过程:
  服务器端:
    01,申请一个socket
    02,绑定到一个IP地址和一个端口上
    03,开启侦听,等待接收连接

客户端:
    01,申请一个socket
    02,指定要连接的服务器(指明服务器的IP地址和端口号)

服务器端:

01.接收到连接请求后,产生一个新的socket(端口大于1024)与客户端建立连接并进行通信(就相当于公司的前台)

02.原监听socket继续监听。

注意:负责通信的Socket不能无限创建,创建的数量和操作系统有关。

2.1  Socket构造函数

Socket的构造函数
    Public Socket(AddressFamily addressFamily,SocketType  socketType,ProtocolType  protocolTYpe)
各参数的含义:

AddressFamily:指定Socket用来解析地址的寻址方案
   SocketType:定义要打开的Socket的类型
   Socket类使用ProtocolType枚举向Windows  Sockets  API通知所请求的协议

注意:
   1,端口号必须在 1 和 65535之间,最好在1024以后(1024以内的端口一般都是系统定义的端口,最好不要占用)。
   2,要连接的远程主机必须正在监听指定端口,也就是说你无法随意连接远程主机。

如:
IPAddress addr = IPAddress.Parse(“192.168.1.118″);
IPEndPoint endp = new IPEndPoint(addr,9000);
         服务端先绑定:serverSocket.Bind(endp)
         客户端再连接:clientSocket.Connect(endp)

3,一个客户端Socket一次只能连接一台主机(服务器端)
   4,Socket关闭后无法再次使用
   5,每个Socket对象只能与一台远程主机连接。如果你想连接到多台远程主机,你必须创建多个Socket对象。

2.2  Socket常用类和方法

相关类:

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

方法:
   Socket():创建一个Socket
   Bind():绑定一个本地的IP和端口号(IPEndPoint)
   Listen():让Socket侦听传入的连接(俗称:等待上线),并指定侦听队列容量
   Connect():初始化与另一个Socket的连接
   Accept():接收连接并返回一个新的Socket
   Send():输出数据到Socket
   Receive():从Socket中读取数据
   Close():关闭Socket,销毁连接

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;namespace ASimpleSocketComm
{public partial class frm_Server : Form{public frm_Server(){InitializeComponent();}//窗体加载事件private void Form1_Load(object sender, EventArgs e){Control.CheckForIllegalCrossThreadCalls = false;}//开始侦听 按钮单击事件private void btn_StartLsn_Click(object sender, EventArgs e){//获取输入框中的IP地址IPAddress myip = IPAddress.Parse(txt_IP.Text);//获取输入框中的端口号int myport = int.Parse(txt_Port.Text);//构建IP终结点IPEndPoint ippoint = new IPEndPoint(myip, myport);//创建监听用的SocketSocket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//解释:第一个参数代表使用IPV4寻址方案,第二个参数是指采用Stream方式进行通信,第三个参数是指基于TCP协议try{//将创建好的socket绑定到具体的IP终结点
                socket.Bind(ippoint);//同一时间最多接收10个客户端上线,多余的需排队socket.Listen(10);//在Server窗体中显示信息txt_SrvMsg.AppendText("服务器开始侦听...\r\n");Thread mythread = new Thread(AcceptInfo);mythread.IsBackground = true;mythread.Start(socket);}catch (Exception ex){txt_SrvMsg.AppendText(ex.Message + "\r\n");}            }//记录通信用的SocketDictionary<string, Socket> dic = new Dictionary<string, Socket>();//侦听并接收客户端上线连接void AcceptInfo(object o){Socket socket = o as Socket;//循环接收消息 死循环while (true){try{//创建通信用的socketSocket tScocket = socket.Accept();string ippoit = tScocket.RemoteEndPoint.ToString();txt_SrvMsg.AppendText(ippoit + "连接成功!\r\n");dic.Add(ippoit, tScocket);//将连接上来的客户端IPPORT保存到dic中cbx_IPEndPoint.Items.Add(ippoit);//将连接上来的客户端IPPORT添加到下拉框中//接收消息Thread th = new Thread(ReceiveMsg);th.IsBackground = true;th.Start(tScocket);}catch (Exception ex){txt_SrvMsg.AppendText(ex.Message + "\r\n");break;}}}//接收客户端发送的消息void ReceiveMsg(object o){Socket client = o as Socket;while (true){//接收客户端发送过来的数据try{//定义byte数组存放从客户端接收到的数据byte[] buffer = new byte[1024 * 1024];//将接收的数据放入buffer中,并返回实际接收数据的长度int n = client.Receive(buffer);//将字节数组转换成字符串string words = Encoding.Default.GetString(buffer, 0, n);//将接收的数据显示到Server窗体中txt_SrvMsg.AppendText(client.RemoteEndPoint.ToString() + ":" + words + "\r\n");}catch (Exception ex){txt_SrvMsg.AppendText(ex.Message + "\r\n");break;}}}//给客户端发送消息 发送消息按钮单击事件private void btn_SendMsg_Click(object sender, EventArgs e){try{//设置发送目标客户端string ipport = cbx_IPEndPoint.Text;//从下拉框中获取选中的目标IPPORTif (ipport == ""){ MessageBox.Show("请选择一个客户端!"); return; }//将要发送的数据转换为byte数组byte[] buffer = Encoding.Default.GetBytes(txt_Send.Text);//发送数据
                dic[ipport].Send(buffer);//将要发送的数据显示到Server窗体中txt_SrvMsg.AppendText(txt_Send.Text + "\r\n");}catch (Exception ex){txt_SrvMsg.AppendText(ex.Message + "\r\n");                }}}
}

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;namespace ASimpleSocketClient
{public partial class frm_Client : Form{public frm_Client(){InitializeComponent();}//窗体加载事件private void frm_Client_Load(object sender, EventArgs e){Control.CheckForIllegalCrossThreadCalls = false;}Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//连接 按钮单击事件private void btn_Connect_Click(object sender, EventArgs e){//需要连接的目标IP(服务器端的IP)IPAddress ip = IPAddress.Parse(txt_IP.Text);//目标端口(服务器端的侦听端口)int port = int.Parse(txt_Port.Text);//构建IP终结点IPEndPoint ippoint = new IPEndPoint(ip, port);try{//连接到服务器
                client.Connect(ippoint);txt_ClientMsg.AppendText("连接成功!" + "\r\n");txt_ClientMsg.AppendText("服务器:" + client.RemoteEndPoint.ToString() + "\r\n");txt_ClientMsg.AppendText("客户端:" + client.LocalEndPoint.ToString() + "\r\n");//连接成功后就可以接收服务器端发送的消息了Thread th = new Thread(ReceiveMsg);th.IsBackground = true;th.Start();}catch (Exception ex){txt_ClientMsg.AppendText(ex.Message + "\r\n");}}//接收服务器端发送的消息void ReceiveMsg(){while (true){try{byte[] buffer = new byte[1024 * 1024];int n = client.Receive(buffer);string s = Encoding.Default.GetString(buffer, 0, n);txt_ClientMsg.AppendText(client.RemoteEndPoint.ToString() + ":" + s + "\r\n");}catch (Exception ex){txt_ClientMsg.AppendText(ex.Message + "\r\n");break;}}}//发送消息 按钮单击事件private void btn_SendMsg_Click(object sender, EventArgs e){//客户端给服务器端发送消息if (client != null){try{byte[] buffer = Encoding.Default.GetBytes(txt_Send.Text);client.Send(buffer);txt_ClientMsg.AppendText(txt_Send.Text + "\r\n");}catch (Exception ex){txt_ClientMsg.AppendText(ex.Message + "\r\n");}}}        }
}

转载于:https://www.cnblogs.com/nocanstillbb/p/8184737.html

socket编程详解,转自http://www.sme-cn.com:82/archives/669相关推荐

  1. PHP SOCKET编程详解

    这篇文章主要介绍了PHP SOCKET编程详解,需要的朋友可以参考下 1. 预备知识 一直以来很少看到有多少人使用php的socket模块来做一些事情,大概大家都把它定位在脚本语言的范畴内吧,但是其实 ...

  2. Linux的SOCKET编程详解

    Linux的SOCKET编程详解 一. 网络中进程之间如何通信 进程通信的概念最初来源于单机系统.由于每个进程都在自己的地址范围内运行,为保证两个相互通信的进 程之间既互不干扰又协调一致工作,操作系统 ...

  3. Linux的SOCKET编程详解——非常叼

    http://blog.csdn.net/hguisu/article/details/7445768/ 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] Linux的SOCKE ...

  4. php里面的socket编程,详解PHP Socket 编程过程

    详解PHP Socket 编程过程 作者:PHPYuan 时间:2019-03-13 03:41:20 概述 Socket用于进程间通信.进程间通信通常基于客户端-服务端模型.此时,客户端-服务端是可 ...

  5. Linux的SOCKET编程详解(转载)

    一. 网络中进程之间如何通信 进程通信的概念最初来源于单机系统.由于每个进程都在自己的地址范围内运行,为保证两个相互通信的进程之间既互不干扰又协调一致工作,操作系统为进程通信提供了相应设施,如: UN ...

  6. Netty的Socket编程详解-搭建服务端与客户端并进行数据传输

    场景 Netty在IDEA中搭建HelloWorld服务端并对Netty执行流程与重要组件进行介绍: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article ...

  7. Java Socket编程详解

    Java Socket编程是Java网络编程很重要的内容,现参考了许多资料,总结如下: 1. Java网络编程原理+Socket编程 http://www.cnblogs.com/linzheng/a ...

  8. C# Socket 编程详解

    Microsoft.Net Framework为应用程序访问Internet提供了分层的.可扩展的以及受管辖的网络服务,其名字空间System.Net和 System.Net.Sockets包含丰富的 ...

  9. C#Socket编程详解(一)TCP与UDP简介

    一.TCP与UDP(转载) 1.TCP 1.1 定义 TCP(TransmissionControl Protocol)传输控制协议. 是一种可靠的.面向连接的协议(eg:打电话).传输效率低全双工通 ...

  10. java 网络io详解_Java网络socket编程详解

    或许有点长 但是一步步教你 我想你也愿意看7.2面向套接字编程 我们已经通过了解Socket的接口,知其所以然,下面我们就将通过具体的案例,来熟悉Socket的具体工作方式7.2.1使用套接字实现基于 ...

最新文章

  1. access 查找工龄大于30_ACCESS查询操作题完整
  2. C#使用TCP/IP与ModBus进行通讯
  3. 如何生成随机不重复的11位数字
  4. 小红书消息中间件的运维实践与治理之路
  5. JDBC的批处理操作三种方式
  6. Python基础import导包问题
  7. django 引用css失效_如何使用Python中Django模板?
  8. vscode we cannot connect_秋季常规赛分秒必争,PC BET直播:TES能否拿下西安WE
  9. Istio 组件详解
  10. 记一次RAID阵列的迁移经历
  11. sga_target大于sga_max_size数据库无法启动
  12. “深度学习”是人工智能的一场革命吗?
  13. MIPS指令集确实够精简,编译文件明显小
  14. 用hyperf框架开发JsonRpc服务
  15. 谷粒商城项目基础篇总结文档
  16. Virtex-4 cameralink开发板PCI图像采集卡定制FPGA-HDMI编码-LVDS相机
  17. VIN码/车架号的详解,车架号识别,VIN码识别,OCR车架号识别能带来什么
  18. 【MATLAB】报错:数组索引必须为正整数或逻辑值
  19. 一个页面中有多个audio标签,其中一个播放结束后自动播放下一个,audio连续播放
  20. 云桌面有哪些优势-为什么企业使用云桌面是趋势

热门文章

  1. 查看Linux版本命令
  2. delphi 2010 mysql_DELPHI 10.2 TOKYO搭建LINUX MYSQL开发环境
  3. python无法启动此程序因为_(python shell怎么用)为啥我按照python安装教程,总说无法启动此程序,因为计算机中丢失?...
  4. python网络编程百度云_python网络编程.mobi
  5. 双系统ubuntu无法进入_win10下安装ubuntu双系统
  6. 如何在linux下运行php脚本,如何通过Linux命令行使用和运行PHP脚本
  7. Web开发HTTP中URI和URL的情感纠葛
  8. 资产管理软件 GLPI的安装(转)
  9. 安装Oracle问题总结
  10. Hadoop MapReduce篇