热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

项目总结——深入浅出socket网络编程

前言:为什么会有如题的概念呢,我想对于没有主动听说过socket网络编程的人来说读到题目可能就已经蒙头了,为了很好的让大家进入场景,首先说一下一个需要用到这点东西的业务需求。首先
前言:

    为什么会有如题的概念呢,我想对于没有主动听说过socket网络编程的人来说读到题目可能就已经蒙头了,为了很好的让大家进入场景,首先说一下一个需要用到这点东西的业务需求。

       首先大家应该明确的是socket网络编程是以CS的模式下才有的,比如机房收费系统,在机房收费系统中可能会遇到不同的机房使用的收费系统是使用同一个数据库的。但是对于一些显示的信息,只有每次查询数据库的时候才能更新到窗体中,拿最简单的主界面的当前上机的人数来说,有机房A和机房B两个机房,并且他们是使用同一个数据库的,然后两个值班教师在同一时间工作,但机房A增加或减少上机的人数,机房B的值班教师是不能实时的接到消息并更新自己的窗体的。这就会导致窗体显示的信息暂时性的错误。这时就用到了我们的socket网络编程。

 

一、官方的解释socket机制:      

       在网络编程中最常用的方案便是Client/Server(客户机/服务器)模型。在这种方案中客户应用程序向服务器程序请求服务。一个服务程序通常在一个众所周知的地址监听对服务的请求,也就是说,服务进程一 直处于休眠状态,直到一个客户向这个服务的地址提出了连接请求。在这个时刻,服务程序被"惊醒"并且为客户提供服务-对客户的请求作出适当的反应。

       为了方便这种Client/Server模型的网络编程,90年代初,由Microsoft联合了其他几家公司共同制定了一套WINDOWS下的网络编程接口,即WindowsSockets规范,它不是一种网络协议,而是一套开放的、支持多种协议的Windows下的网络编程接口。现在的Winsock已经基本上实现了与协议无关,你可以使用Winsock来调用多种协议的功能,但较常使用的是TCP/IP协议。Socket实际在计算机中提供了一个通信端口,可以通过这个端口与任何一个具有Socket接口的计算机通信。应用程序在网络上传输,接收的信息都通过这个Socket接口来实现。

 

二、通俗的理解socket

       我们可以简单的把Socket理解为一个可以连通网络上不同计算机程序之间的管道,把一堆数据从管道的A端扔进去,则会从管道的B端(也许同时还可以从C、D、E、F……端冒出来)。管道的端口由两个因素来唯一确认,即机器的IP地址和程序所使用的端口号。IP地址的含义所有人都知道,所谓端口号就是程序员指定的一个数字,许多著名的木马程序成天在网络上扫描不同的端口号就是为了获取一个可以连通的端口从而进行破坏。比较著名的端口号有http的80端口,当然,建议大家自己写程序不要使用太小的端口号,它们一般被系统占用了,也不要使用一些著名的端口,一般来说使用1000~5000之内的端口比较好。

       Socket可以支持数据的发送和接收,它会定义一种称为套接字的变量,发送数据时首先创建套接字,然后使用该套接字的send等方法对准某个IP/端口进行数据发送;接收端也首先创建套接字,然后将该套接字绑定到一个IP/端口上,所有发向此端口的数据会被该套接字的recv等函数读出。如同读出文件中的数据一样。

 

三、例子:

       说了这么多我想大家对于socket有了简单的认识,当然还是要在代码中深入的理解。

       在看代码之前,还要做最后的解释,socket编程一定使用客户端和服务器的,虽然接下来的例子中只是一对一的通信,但其实和一对多的通信是一个原理的。

 

1.服务器代码

首先看服务器代码:

/*********************************************************
* 开发人员:韩义
* 创建时间:2013/9/27 13:51:48
* 描述说明:socket网络变成实例服务器
* 版本:1.0
* 版权所有:信息技术提高班
* *******************************************************/
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;

namespace Server
{
public partial class server : Form
{

Socket s = null;
IPEndPoint iep = null;
byte[] buf = new byte[1024];
Socket worker = null;

public server()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
//启动服务器。--韩义
private void button1_Click_1(object sender, EventArgs e)
{
//创建一个通道
s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

//创建一个侦听点
iep = new IPEndPoint(IPAddress.Any, 20000);

//绑定到通道上
s.Bind(iep);

//侦听
s.Listen(6);
//通过异步来处理,开启监听连接,并交给Accept函数处理连接
s.BeginAccept(new AsyncCallback(Accept), s);
this.button1.Visible = false;
}

//接收到连接的动作--韩义
void Accept(IAsyncResult ia)
{
//获取用户定义的对象,它限定或包含关于异步操作的信息。
s = ia.AsyncState as Socket;//此属性返回一个对象,该对象是启动异步操作的方法的最后一个参数。
worker = s.EndAccept(ia);//返回一个 Socket,它处理与远程主机的通信。
s.BeginAccept(new AsyncCallback(Accept), s);//重新接收链接,并制定回掉函数

try
{
//开始接受数据
worker.BeginReceive(buf, 0, buf.Length, SocketFlags.None, new AsyncCallback(Receive), worker);
}
catch
{ throw; }
}

//收到消息的动作--韩义
void Receive(IAsyncResult ia)
{
//获取用户定义的对象,它限定或包含关于异步操作的信息。
worker = ia.AsyncState as Socket;
//获取数据长度
int count = worker.EndReceive(ia);
//自己开始接收数据。
worker.BeginReceive(buf, 0, buf.Length, SocketFlags.None, new AsyncCallback(Receive), worker);
//按GB2312的标准取出数据
string cOntext= Encoding.GetEncoding("gb2312").GetString(buf, 0, count);
this.textBox1.Text += Environment.NewLine;
this.textBox1.Text += context;
}
//发送消息--韩义
private void button2_Click_1(object sender, EventArgs e)
{
string cOntext= "管理员:" + this.textBox2.Text.Trim();

if (context != "")
{
this.textBox1.Text += Environment.NewLine;//换行
this.textBox1.Text += context;
this.textBox2.Text = "";
worker.Send(Encoding.GetEncoding("gb2312").GetBytes(context));
}
}
}
}

2.服务器界面:


3.客户端代码

/*********************************************************
* 开发人员:韩义
* 创建时间:2013/9/27 13:51:48
* 描述说明:socket网络变成实例客户端
* 版本:1.0
* 版权所有:信息技术提高班
* *******************************************************/
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;

namespace Client
{
public partial class client : Form
{
Socket s = null;
IPEndPoint iep = null;
byte[] buf = new byte[1024];

public client()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
//连接服务器--韩义
private void button1_Click_1(object sender, EventArgs e)
{
s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"),20000);
try
{
s.Connect(iep); //建立与远程主机的连接
this.label1.Text = "连接成功";//连接成功提示
this.button1.Visible = false;//隐藏连接按钮
}
catch
{ throw; }
try
{
//开始接收连接。
s.BeginReceive(buf, 0, buf.Length, SocketFlags.None, new AsyncCallback(Receive), s);
}
catch
{ throw; }
}
//发送消息--韩义
private void button2_Click_1(object sender, EventArgs e)
{
string cOntext= iep.ToString() + ":" + this.textBox2.Text.Trim();
if (context != "")
{
this.textBox1.Text += Environment.NewLine;
this.textBox1.Text += context;
this.textBox2.Text = "";
//发送消息
s.Send(Encoding.GetEncoding("gb2312").GetBytes(context));
}
}

//收到消息的动作--韩义
void Receive(IAsyncResult ia)
{
s = ia.AsyncState as Socket;
int count = s.EndReceive(ia);
//自己开始接收数据
s.BeginReceive(buf, 0, buf.Length, SocketFlags.None, new AsyncCallback(Receive), s);
string cOntext= Encoding.GetEncoding("gb2312").GetString(buf, 0, count);
this.textBox1.Text += Environment.NewLine;
this.textBox1.Text += context;
}
}
}

4.客户端界面:


        当然大家会发现其实这就是一个聊天工具,和一个好友聊天就是一对一,群聊天就是一对多。这又进一步的帮助理解网络编程的含义。

 

四、总结:

       通过以上的代码,我们可以大概的总结一下socket编程的几个步骤:

  1. 建立Socket

在服务器端建立一个监听的Socket,为此可以调用Socket()函数用来建立这个监听的Socket,并定义此Socket所使用的通信协议。此函数调用成功返回Socket对象,失败则返回INVALID_SOCKET

初始化调用的socket的构造函数,MSDN上共有三种构造函数重载,这里我们用的是第三种

Socket(AddressFamily, SocketType, ProtocolType)

使用指定的地址族、套接字类型和协议初始化 Socket 类的新实例。

  1. 绑定端口

接下来要为服务器端定义的这个监听的Socket指定一个地址及端口(Port),这样客户端才知道待会要连接哪一个地址的哪个端口,为此我们要调用bind()函数,该函数调用成功返回0,否则返回SOCKET_ERROR。

  1. 监听

当服务器端的Socket对象绑定完成之后,服务器端必须建立一个监听的队列来接收客户端的连接请求。listen()函数使服务器端的Socket进入监听状态,并设定可以建立的最大连接数(目前最大值限制为 6, 最小值为1)。该函数调用成功返回0,否则返回SOCKET_ERROR。

  1. 服务器端接受客户端的连接请求

当Client提出连接请求时,Server端监听视窗会收到客户端送来我们自定义的一个消息,这时,我们可以分析lParam,然后调用相关的函数来处理此事件。为了使服务器端接受客户端的连接请求,就要使用accept()函数,该函数新建一Socket与客户端的Socket相通,原先监听之Socket继续进入监听状态,等待他人的连接要求。该函数调用成功返回一个新产生的Socket对象,否则返回INVALID_SOCKET。

 

       以上可以说是socket网络编程的核心内容。其实真的没有那么难理解

特别说明:
  1. 本实例只是一对一的通信,一对多的通信或多对多的通信只需在此基础上略加改动。
  2. 本实例只是很简单的小例子,有需要复用的代码请注意命名规范。


推荐阅读
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • CentOS 6.5安装VMware Tools及共享文件夹显示问题解决方法
    本文介绍了在CentOS 6.5上安装VMware Tools及解决共享文件夹显示问题的方法。包括清空CD/DVD使用的ISO镜像文件、创建挂载目录、改变光驱设备的读写权限等步骤。最后给出了拷贝解压VMware Tools的操作。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
author-avatar
闺蜜好我会明白
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有