.net 网络编程
1、首先说下计算机网络中的TCP/IP参考模型
TCP/IP把网络分为5层,每一层负责完成不同的功能
1)应用层:传输报文,提供各种网络应用,有FTP、SMTP、HTTP等协议
2)运输层:传输报文段,为应用程序的客户机和服务器之间提供传输应用层报文服务,协议有TCP,UDP
3)网络层:传输数据包,协议有IP协议,选路协议
4)链路层:传输数据帧,以太网就属于这个层
5)物理层:在节点之间传输比特流
应用程序是通过套接字访问网络下层的服务的,套接字是网络运输层和应用层的一个编程接口,在程序中通过套接字来进行TCP和UDP传输,运输层以下的层对程序员透明
TCP和UDP是最基本的传输协议,应用层的所有协议都是基于这两个协议进行封装扩展的
TCP:可靠的,面向连接的连接数据传输服务,传输的是字节流,能保证数据的有序性
1)建立连接(三次握手) 2)传输数据 3)断开连接(四次握手)
UDP:不可靠,面向数据报的无连接的数据传输服务,传输的是是数据包,不保证数据的有序性
广播:可以向同一个子网内的所有主机发送广播数据
组播:可以向所有加入组网的主机发送组播数据
2、编程(本节由于篇幅太长,这里只说TCP)
.NET 框架提供了下面几个类对实现网络通信:
Socket:提供最基本的TCP和UDP服务
TcpListener/TcpClient 和 UdpClient:对Socket类进行了基本封装
NetworkStream:网络流,对网络数据的写入和读取
使用套接字的步骤
TCP:服务器:创建套接字 -》 绑定套接字Bind -》 监听套接字Listen -》 接受连接Accept -》 发送/接受Send/Receive -》 关闭套接字CLose
:客户端:创建套接字 -》 连接 -》 发送/接受Send/Receive -》 关闭套接字CLose
UDP:创建套接字 -》 绑定套接字Bind -》 发送/接受SendTo/ReceiveFrom -》 关闭套接字CLose
1)Socket(使用异步方式连接和收发信息,因为等待连接和等待数据的时候会让主线程阻塞)
这里就不贴代码了,跟下面的差不多,后面下载的代码有(我用的VS2012,低版本不能查看可以直接看源文件的代码)
2)TcpListener/TcpClient(这里也使用异步方式来连接和接收信息)
首先创建一个异步用的数据对象
public class StateObject
{
public NetworkStream networkstream = null;
public byte[] buffer = new byte[1024];
public StateObject(NetworkStream netstream)
{
this.networkstream = netstream;
}
}
1)服务器端(异步监听,当收到连接,则异步读取数据,注意捕获连接断开时的异常)
TcpListener listener;
NetworkStream networkstream; private void btnBind_Click(object sender, EventArgs e)
{
//绑定,启动异步接受连接
try
{
int port = int.Parse(tbPort.Text);
IPAddress ipaddress = IPAddress.Parse(tbIP.Text);
IPEndPoint endpoint = new IPEndPoint(ipaddress, port); listener = new TcpListener(endpoint);
listener.Start(10); //监听数位10
//开始异步接收连接请求
listener.BeginAcceptTcpClient(DoAcceptTcpClientCallback, listener);
btn.Text = "Close";
}
catch (ArgumentNullException) { }
catch (SocketException) { }
}
//异步接收请求函数
public void DoAcceptTcpClientCallback(IAsyncResult ar)
{
TcpListener listener = (TcpListener)ar.AsyncState;
try
{
TcpClient client = listener.EndAcceptTcpClient(ar);
//收到连接
this.BeginInvoke(new ThreadStart(() =>
{
//收到连接请求,这里可以让主线程更新UI
}));
networkstream = new NetworkStream(client.Client);
StateObject so = new StateObject(networkstream); //开始异步读取数据
networkstream.BeginRead(so.buffer, 0, so.buffer.Length, ReadCallback, so); //如果需要继续监听,则继续异步接收
listener.BeginAcceptTcpClient(DoAcceptTcpClientCallback, listener);
}
catch (ObjectDisposedException)
{
//Socket关闭
}
}
//异步读取数据函数
public void ReadCallback(IAsyncResult ar)
{
StateObject so = (StateObject)ar.AsyncState;
try
{
NetworkStream myNetworkStream = so.networkstream;
int length = myNetworkStream.EndRead(ar);
string receivemsg = Encoding.UTF8.GetString(so.buffer, 0, length);
this.BeginInvoke(new ThreadStart(() =>
{
//收到数据,在这里可以让主线程更新UI
}));
so.buffer = new byte[1024];
//继续接收数据
myNetworkStream.BeginRead(so.buffer, 0, so.buffer.Length, ReadCallback, so);
}
catch (IOException)
{
this.BeginInvoke(new ThreadStart(() =>
{
//连接断开
}));
networkstream = null;
}
}
这样,服务器端就完成了监听
2)客户端(同样通过异步实现)
TcpClient client;
NetworkStream networkstream;
private void btnConnect_Click(object sender, EventArgs e)
{
int port = int.Parse(tbPort.Text);
IPAddress ipaddress = IPAddress.Parse(tbIP.Text);
IPEndPoint endpoint = new IPEndPoint(ipaddress, port); if (client == null)
{
//开始异步连接
client = new TcpClient();
client.BeginConnect(ipaddress, port, ConnectCallback, client);
}
}
private void ConnectCallback(IAsyncResult ar)
{ TcpClient t = ar.AsyncState as TcpClient;
try
{
t.EndConnect(ar);
networkstream = t.GetStream();
this.BeginInvoke(new ThreadStart(() =>
{
//连接成功
}));
//开始异步接受数据
StateObject so = new StateObject(networkstream);
networkstream.BeginRead(so.buffer, 0, so.buffer.Length, ReadCallback, so);
}
catch (SocketException)
{
this.BeginInvoke(new ThreadStart(() =>
{
//连接失败,让UI更新
}));
}
}
public void ReadCallback(IAsyncResult ar)
{
StateObject so = (StateObject)ar.AsyncState;
try
{
NetworkStream myNetworkStream = so.networkstream;
int length = myNetworkStream.EndRead(ar);
string receivemsg = Encoding.UTF8.GetString(so.buffer, 0, length);
this.BeginInvoke(new ThreadStart(() =>
{
//更新UI
}));
//继续异步接受数据
so.buffer = new byte[1024];
myNetworkStream.BeginRead(so.buffer, 0, so.buffer.Length, ReadCallback, so);
}
catch (IOException)
{
this.BeginInvoke(new ThreadStart(() =>
{
//连接断开
}));
networkstream = null;
}
}
3)接下来是发送数据
private void btnSend_Click(object sender, EventArgs e)
{
if (networkstream != null)
{
byte[] sendbyte = System.Text.Encoding.UTF8.GetBytes("你好:)");
networkstream.Write(sendbyte, 0, sendbyte.Length);
}
else
{
tbMsg.AppendText("未连接\n");
}
}
具体项目代码 http://files.cnblogs.com/bomo/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B.zip
.net 网络编程的更多相关文章
- 猫哥网络编程系列:HTTP PEM 万能调试法
注:本文内容较长且细节较多,建议先收藏再阅读,原文将在 Github 上维护与更新. 在 HTTP 接口开发与调试过程中,我们经常遇到以下类似的问题: 为什么本地环境接口可以调用成功,但放到手机上就跑 ...
- python select网络编程详细介绍
刚看了反应堆模式的原理,特意复习了socket编程,本文主要介绍python的基本socket使用和select使用,主要用于了解socket通信过程 一.socket模块 socket - Low- ...
- Linux Socket 网络编程
Linux下的网络编程指的是socket套接字编程,入门比较简单.在学校里学过一些皮毛,平时就是自学玩,没有见识过真正的socket编程大程序,比较遗憾.总感觉每次看的时候都有收获,但是每次看完了之后 ...
- 猫哥网络编程系列:详解 BAT 面试题
从产品上线前的接口开发和调试,到上线后的 bug 定位.性能优化,网络编程知识贯穿着一个互联网产品的整个生命周期.不论你是前后端的开发岗位,还是 SQA.运维等其他技术岗位,掌握网络编程知识均是岗位的 ...
- 浅谈C#网络编程(一)
阅读目录: 基础 Socket编程 多线程并发 阻塞式同步IO 基础 在现今软件开发中,网络编程是非常重要的一部分,本文简要介绍下网络编程的概念和实践. Socket是一种网络编程接口,它是对传输层T ...
- C++11网络编程
Handy是一个简洁优雅的C++11网络库,适用于linux与Mac平台.十行代码即可完成一个完整的网络服务器. 下面是echo服务器的代码: #include <handy/handy.h&g ...
- Java - 网络编程
Java的网络编程学习,关于计算机基础的学习参考:计算机网络基础学习 - sqh. 参考:
- Linux网络编程-IO复用技术
IO复用是Linux中的IO模型之一,IO复用就是进程预先告诉内核需要监视的IO条件,使得内核一旦发现进程指定的一个或多个IO条件就绪,就通过进程进程处理,从而不会在单个IO上阻塞了.Linux中,提 ...
- Python Socket 网络编程
Socket 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的,例如我们每天浏览网页.QQ ...
- iOS网络编程
今天的重点是UIWebView.NSURLSession.JSon. 网络编程联网准备:1.在Info.plist中添加AppTransportSecurity类型Dictionary:2.在AppT ...
随机推荐
- linux查看是什么操作系统是什么命令
https://zhidao.baidu.com/question/361519585968730492.html
- win 文字转化为语音
mshta vbscript:createobject("sapi.spvoice").speak("hello")(window.close)
- 接口测试第三课(HTTP协议简介) -- 转载
一.打开百度URL详解: 用浏览器打开百度网址,输入任意关键字搜索后: 详细URL地址复制出来如下 https://www.baidu.com/s?ie=utf-8&f=8&rsv_b ...
- React 学习,需要注意几点
最近要开始学习 React 框架了,在学习的过程中,个人作为一个新手觉得需要注意的一些问题 小细节有以下几点: 1:在JSX语法当中,如果遇到 HTML 标签(以 < 开头),将用 HTML 规 ...
- jpeg相关知识
一.jpeg介绍 JPEG 是 Joint Photographic Exports Group 的英文缩写,中文称之为联合图像专家小组.该小组隶属于 ISO 国际标准化组织,主要负责定制静态数字图像 ...
- paramiko模块的安装
1.找到自己python安装的目录(默认路径:C:\Users\zhangliyuan\AppData\Local\Programs\Python\Python35) 注:cmd中所有命令 2.进入S ...
- android webView开发之js调用java代码示例
1.webView设置 webView.getSettings().setJavaScriptEnabled(true);//设置支持js webView.addJavascriptInterface ...
- sql查询重复数据
select *from Awhere id in (select id from A group by id having count(1) >= 2) 注释:id 为重复的关键字(更换成所需 ...
- spring和Hibernate整合
首先导入spring和Hibernate的jar包,以及JDBC和c3p0的jar包, 然后就是Hibernate的XML配置文件,不需要加入映射文件,这里用spring容器管理了. Hibernat ...
- 百度编辑器ueditor的简单使用
最近刚被分配了以个消息发布的任务,其中用到了富文本编辑器.以前也用过,不过这次我选择的是百度富文本编辑器ueditor1_4_3-utf8-jsp版的. 其实看ueditor功能很强大,不过百度的设计 ...