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. C语言中使用系统自带的快排函数

    题目 . 德才论 () 宋代史学家司马光在<资治通鉴>中有一段著名的"德才论":"是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人.凡取 ...

  2. python 引用传递与值传递

    https://taizilongxu.gitbooks.io/stackoverflow-about-python/content/16/README.html 1.也就是如果传可变对象,就是引用传 ...

  3. [ACM训练] 算法初级 之 搜索算法 之 深度优先算法DFS (POJ 2251+2488+3083+3009+1321)

    对于深度优先算法,第一个直观的想法是只要是要求输出最短情况的详细步骤的题目基本上都要使用深度优先来解决.比较常见的题目类型比如寻路等,可以结合相关的经典算法进行分析. 常用步骤: 第一道题目:Dung ...

  4. C语言中函数声明实现的位置

    在学习C语言的时候我遇到了这么个事情,因为之前先学习的C#,在C#编译器中,函数的声明位置不会影响编译的结果,但是在C语言中却发生了错误 先看一段代码: #include <stdio.h> ...

  5. 初步了解CPU

    了解CPU By JackKing_defier 首先说明一下,本文内容主要是简单说明CPU的大致原理,所需要的前提知识我会提出,但是由于篇幅我不会再详细讲解需要的其他基础知识.默认学过工科基础课. ...

  6. AMD与CMD(转载)

    JavaSript模块化   在了解AMD,CMD规范前,还是需要先来简单地了解下什么是模块化,模块化开发?       模块化是指在解决某一个复杂问题或者一系列的杂糅问题时,依照一种分类的思维把问题 ...

  7. 安卓(android)之实现断点下载功能

    一.建立实体类 1.文件实体类 package com.example.zjw.myapplication.dao; import java.io.Serializable; /** * 预下载文件实 ...

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

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

  9. Python使用总结二

    近来因为工作需要,用Python比较多,写得多了,收获也多.借此记录总结一下,方便以后反思. 一.IDE的选择 1.notepad++加上cmd窗口 前些时候写python脚本都用notepad++编 ...

  10. nodejs学习之加密

    Nodejs中的加密是Crypto模块, 1.md5的使用 var crypto = require("crypto"); //创建 var md5 = crypto.create ...