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. Set和存储顺序

    set(interface) 存入Set的每个元素必须是唯一的,因为Set不保存重复的元素.加入Set的元素必须定义 equal()方法以确保对象的唯一性.Set和Collection有完全一样的接口 ...

  2. storm学习好文链接

    大圆的那些事:http://www.cnblogs.com/panfeng412/tag/Storm/ xcc的博客:http://blog.csdn.net/damacheng/article/ca ...

  3. Linux tricks

    Environment Settings Path Globally set path is in /etc/profile; or the user's .bash_profile for part ...

  4. paramiko模块的安装

    1.找到自己python安装的目录(默认路径:C:\Users\zhangliyuan\AppData\Local\Programs\Python\Python35) 注:cmd中所有命令 2.进入S ...

  5. java反射学习之一反射机制概述

    一.反射机制背景概述 1.反射(reflection)是java被视为动态语言的一个关键性质 2.反射机制指的是程序在运行时能获取任何类的内部所有信息 二.反射机制实现功能概述 1.只要给定类的全名, ...

  6. 【codevs】刷题记录→_→(推荐看!)

    注:本文是我原先在csdn内写的一篇博文,现转到这里,两篇博文尽量同时更新. //#include<iostream->shuati> //define 为什么刷  学长☞hzwer ...

  7. 基于struts2和hibernate的分页实现

    在拜读了各位大牛的博客后,加以修改和添加总算是借鉴出了一个可行的分页实现.(●'◡'●) 话不多说,先贴两张效果图吧 接下来是实现代码: pagingDAOImpl.java public class ...

  8. RBAC模型速记

    RBAC Model core concept: user,role,permission,operation,resource user has many roles, assign role to ...

  9. EF联合查询,如何设置条件过滤从表数据

    最近在使用EF进行联合查询过程中,遇到了一件不开心的事情. 已禁用懒加载 var post = await _repository.GetMyPostById(blogId, postId).AsNo ...

  10. CI-持续集成(2)-软件工业“流水线”技术实现

    1   概述 持续集成(Continuous Integration)是一种软件开发实践.在本系列文章的前一章节已经对其背景及理论体系进行了介绍.本小节则承接前面提出的理论构想进行具体的技术实现. & ...