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 网络编程的更多相关文章

  1. 猫哥网络编程系列:HTTP PEM 万能调试法

    注:本文内容较长且细节较多,建议先收藏再阅读,原文将在 Github 上维护与更新. 在 HTTP 接口开发与调试过程中,我们经常遇到以下类似的问题: 为什么本地环境接口可以调用成功,但放到手机上就跑 ...

  2. python select网络编程详细介绍

    刚看了反应堆模式的原理,特意复习了socket编程,本文主要介绍python的基本socket使用和select使用,主要用于了解socket通信过程 一.socket模块 socket - Low- ...

  3. Linux Socket 网络编程

    Linux下的网络编程指的是socket套接字编程,入门比较简单.在学校里学过一些皮毛,平时就是自学玩,没有见识过真正的socket编程大程序,比较遗憾.总感觉每次看的时候都有收获,但是每次看完了之后 ...

  4. 猫哥网络编程系列:详解 BAT 面试题

    从产品上线前的接口开发和调试,到上线后的 bug 定位.性能优化,网络编程知识贯穿着一个互联网产品的整个生命周期.不论你是前后端的开发岗位,还是 SQA.运维等其他技术岗位,掌握网络编程知识均是岗位的 ...

  5. 浅谈C#网络编程(一)

    阅读目录: 基础 Socket编程 多线程并发 阻塞式同步IO 基础 在现今软件开发中,网络编程是非常重要的一部分,本文简要介绍下网络编程的概念和实践. Socket是一种网络编程接口,它是对传输层T ...

  6. C++11网络编程

    Handy是一个简洁优雅的C++11网络库,适用于linux与Mac平台.十行代码即可完成一个完整的网络服务器. 下面是echo服务器的代码: #include <handy/handy.h&g ...

  7. Java - 网络编程

    Java的网络编程学习,关于计算机基础的学习参考:计算机网络基础学习 - sqh.     参考:  

  8. Linux网络编程-IO复用技术

    IO复用是Linux中的IO模型之一,IO复用就是进程预先告诉内核需要监视的IO条件,使得内核一旦发现进程指定的一个或多个IO条件就绪,就通过进程进程处理,从而不会在单个IO上阻塞了.Linux中,提 ...

  9. Python Socket 网络编程

    Socket 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的,例如我们每天浏览网页.QQ ...

  10. iOS网络编程

    今天的重点是UIWebView.NSURLSession.JSon. 网络编程联网准备:1.在Info.plist中添加AppTransportSecurity类型Dictionary:2.在AppT ...

随机推荐

  1. 分布式平台Spark环境的搭建

    1.安装Spark之前需要先安装Java,Scala及Python(个人喜欢用pyspark,当然你也可以用原生的Scala) 首先安装Java jdk: 我们可以在Oracle的官网下载Java S ...

  2. ubuntu server 搭建自己的个人博客及其他网站

    一, 安装apache2服务器 sudo apt-get install apache2 二,安装mysql服务器 sudo apt-get install mysql-server 此时会提示输入M ...

  3. 斯考特·杨(Scott Young)快速学习方法

    上午在网上看到了斯考特·杨(Scott Young)的快速学习方法,感觉很受鼓舞. 现在已经读研究生了,可是发现自己自从上大学以来到现在,发现自己的学习方法有很大的问题. 我是个特别喜欢读书的人,在大 ...

  4. placeholder js简单实现

    window.onload = function() { var input = document.getElementById("input"); input.onblur = ...

  5. Android RecyclerView 的简单使用

    Android L SDK发布的,新API中最有意思的就是RecyclerView (后面为RV) 和 CardView了, 按照官方的说法, RV 是一个ListView 的一个更高级更灵活的一个版 ...

  6. IntelliJ IDEA全键盘操作

    IntelliJ IDEA 如何做到全键盘操作呢? 1.自定义快捷键实现全屏操作 你可以设置自定义快捷键进入全屏操作,并实现各个窗口之间的切换.这样,你就可以告别小窗口的时代,体验全屏显示的效果了!( ...

  7. oracle 字符串分割

    ); create or replace function strsplit2(p_value varchar2, p_split varchar2 := ',') return str_split ...

  8. ADO.NET-SqlHelper

    class Sqlhelper { //数据库连接字符 private static string connstr = ConfigurationManager.ConnectionStrings[& ...

  9. Log4Net异常日志记录在asp.net mvc3.0的应用

    前言 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介.本文主要是简单的介绍如何在Visual ...

  10. QComboBox的activated与currentIndexChanged的区别

    void activated ( int index ) void activated ( const QString & text ) 信号activated是只要单击选择框即使所选内容选择 ...