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

.NET网络编程学习(二)

System.Net.Sockets有很多类,其中最重要的就是Socket类.Socket类publicclassSocket:IDisposableSocket类为网络通信提供了

System.Net.Sockets有很多类,其中最重要的就是Socket类.

 

Socket类
public class Socket : IDisposable
Socket 类为网络通信提供了一套丰富的方法和属性。Socket 类允许您使用 ProtocolType 枚举中所列出的任何一种协议执行异步和同步数据
传输。

 

public Socket(AddressFamily addressFamily,SocketType socketType,ProtocolType protocolType);

其中,addressFamily 参数指定Socket使用的寻址方案,比如AddressFamily.InterNetwork表明为IP版本4的地址;socketType参数指定 Socket的类型,比如SocketType.Stream表明连接是基于流套接字的,而SocketType.Dgram表示连接是基于数据报套接字的。protocolType参数指定Socket使用的协议,比如ProtocolType.Tcp表明连接协议是运用TCP协议的,而 Protocol.Udp则表明连接协议是运用UDP协议的。

 

Socket 类对异步方法遵循 .NET Framework 命名模式。例如,同步的 Receive 方法对应于异步的 BeginReceive 和 EndReceive 方法。

(1)如果当前使用的是面向连接的协议(如 TCP),则服务器可以使用 Listen 方法侦听连接。Accept 方法处理任何传入的连接请求,并返回可用于与远程主机进行数据通信的 Socket。可以使用此返回的 Socket 来调用 Send 或 Receive 方法。如果要指定本地 IP 地址和端口号,请在调用 Listen 方法之前先调用 Bind 方法。如果您希望基础服务提供程序为您分配可用端口,请使用端口号 0。如果希望连接到侦听主机,请调用 Connect 方法。若要进行数据通信,请调用 Send 或 Receive 方法。

(2)如果当前使用的是无连接协议(如 UDP),则根本不需要侦听连接。调用 ReceiveFrom 方法可接受任何传入的数据报。使用 SendTo 方法可将数据报发送到远程主机。

 

同步模式的Socket编程的基本过程如下:
(1)创建一个Socket实例对象。
(2)将上述实例对象连接到一个具体的终结点(EndPoint)。
(3)连接完毕,就可以和服务器进行通讯:接收并发送信息。
(4)通讯完毕,用ShutDown()方法来禁用Socket。
(5)最后用Close()方法来关闭Socket。

 

对于基于Tcp的Socket,涉及到服务器端的侦听(Listen)和客户端的连接(Connect)

以下通过一个简单的Http服务器程序来看看服务器端的程序设计:

(1)BaseConnection是个封装Socket表示一个连接的类.

ContractedBlock.gifExpandedBlockStart.gifCode
public class BaseConnection
{
        Socket sock;
        
public BaseConnection(Socket sock)
        {
            
this.sock = sock;
        }
        
//把客户端请求文件中的字符替换掉
        string ProcessString(string input)
        {
            StringBuilder result 
= new StringBuilder();
            
for (int i &#61; 0; i < input.Length; i&#43;&#43;)
            {
                
if (input[i] &#61;&#61; &#39;/&#39;)
                {
                    result.Append(
&#39;\\&#39;);
                }
                
else
                {
                    result.Append(input[i]);
                }
            }
            
return result.ToString();
        }
        
/// 
        
/// 读取请求信息,返回客户端请求的文件名
        
/// 

        
/// 
        public string getRequest()  
        {
            
string s &#61; null ;
            
byte[] buff &#61; new byte[1024];
            
int recCount &#61; 0;
            
try
            {
                
//从socket读取请求信息
                recCount &#61; sock.Receive(buff, buff.Length, SocketFlags.None);
                s 
&#61; ASCIIEncoding.ASCII.GetString(buff, 0, recCount);
                Console.WriteLine(
"请求的详细信息是:" &#43; s);
                
if (s.IndexOf("GET"> -1)
                {
                    s 
&#61; s.Substring(5);
                    
int fend &#61; s.IndexOf(" ");
                    s 
&#61; s.Substring(0, fend); //取得请求文件的路径及文件名
                }
                
return ProcessString(s);
            }
            
catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            
return "";
        }
        
/// 
        
/// 返回客户端请求的文件
        
/// 

        
/// 
        public void sendResponse(string fname) 
        {
            
byte[] buff &#61; new byte[1024];
            
string filePath &#61; &#64;"C:\Inetpub\wwwroot\" &#43; fname;

            
int count &#61; 0;
            
if (filePath.IndexOf(".."> -1//使访问的文件限制在目录C:\Inetpub\wwwroot\下
            {
                Console.WriteLine(
"没有权限访问!");
                
return;
            }
            Console.WriteLine(
"look for " &#43; filePath);
            
if (File.Exists(filePath)) //检查文件是否存在
            {
                
using (BinaryReader fs &#61; new BinaryReader(File.Open(filePath, FileMode.Open)))
                {
                    
while ((count &#61; fs.Read(buff, 01024)) > 0)
                    {
                        sock.Send(buff, count, SocketFlags.None);
//发送信息
                    }
                }
            }
            
else
            {
                
throw new FileNotFoundException("文件:" &#43; filePath &#43; "不存在!");
            }
        }
        
public void ConClose()  //关闭socket
        {
            sock.Shutdown(SocketShutdown.Both);
            sock.Close();
        }
}

(2)Main方法

 

ContractedBlock.gifExpandedBlockStart.gifCode
        static void Main(string[] args)
        {
            Socket ssock 
&#61; new Socket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp);

            IPAddress hostIp 
&#61; Dns.GetHostEntry("localhost").AddressList[0];
            IPEndPoint ep 
&#61; new IPEndPoint(hostIp, 80);
            ssock.Bind(ep); 
//绑定

            Console.WriteLine(
"开始侦听.");
            
//开始侦听
            ssock.Listen(32);
            
while (true)
            {
                Socket sock 
&#61; ssock.Accept(); //等待客户端请求

                Console.WriteLine(
"有一个客户端请求");
                BaseConnection client 
&#61; new BaseConnection(sock);
                
try
                {
                    
string file &#61; client.getRequest();
                    Console.WriteLine(
"客户端请求的文件是:" &#43; file);
                    client.sendResponse(file);
                }
                
catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
                
finally
                {
                    client.ConClose(); 
//关闭连接
                }
                Console.WriteLine(
"结束一个请求");
                Console.WriteLine(
"");
            }
        }

 

(3)测试
假设在你C:\Inetpub\wwwroot目录下有一个info.html

启动服务器端:

打开浏览器输入:http://localhost/info.html

 结果如下:

同时服务器端输出:

虽然很简单,但我们却的确写了一个http服务器程序.

 

主要参考资料:MSDN



推荐阅读
  • java local socket_网络通信之Socket与LocalSocket的比较
    Socket与LocalSocket都可以实现网络通信,两个有什么区别呢?LocalSocket其通信方式与Socket差不多,只是Loc ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • UML 包图
    什么是包包可直接理解为命名空间,文件夹,是用来组织图形的封装,包图可以用来表述功能组命名空间的组织层次。•在面向对象软件开发的视角中&#x ... [详细]
  • 并不是上一个用SocketServer的聊天室的延续。用远程调用完成的聊天室。正好有Java的RMI聊天室的作业,就先用Python写了一个简单的类似远程调用的东西& ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文介绍了Perl的测试框架Test::Base,它是一个数据驱动的测试框架,可以自动进行单元测试,省去手工编写测试程序的麻烦。与Test::More完全兼容,使用方法简单。以plural函数为例,展示了Test::Base的使用方法。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 今天搭建了redis环境,使用自带的benchmark进行了性能测试选择测试键的范围大小默认情况下面,基准测试使用单一的key。在一个基于内存的数据库里,单一key测试和真实情况下 ... [详细]
  • python图书管理系统类_Python标准库socketserver使用线程混入实现异步TCP服务器
    推荐图书:《Python程序设计开发宝典》,ISBN:978-7-302-47210-0,董付国,清华大学出版 ... [详细]
  • Socketsend函数和recv函数详解send函数intsend(SOCKETs,constcharFAR*buf,intlen,intflags);不论是客户还是服务器应用程 ... [详细]
  • php怎么做rpc通信(RPC通信)
    导读:很多朋友问到关于php怎么做rpc通信的相关问题,本文编程笔记就来为大家做个详细解答,供大家参考,希望对大家有所帮助!一起来看看吧!本文目录一览: ... [详细]
  • Linux问题故障定位
    有时候会遇到一些疑难杂症,并且监控插件并不能一眼立马发现问题的根源。这时候就需要登录服务器进一步深入分析问题的根源。那么分析问题需要有一定的技术经验积累,并且有些问题涉及到的领域非 ... [详细]
author-avatar
FC青春一路有你
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有