TCP/IP协议作为现代网络通讯的基石,内容包罗万象,直接去理解理论是比较困难的;然而通过实践先理解网络通讯的理解,在反过来理解学习TCP/IP协议栈就相对简单很多。C#通过提供的Socket API实现了对TCP/IP协议栈的封装,让实现C/S模型变得更加简单,对于入门TCP/IP协议学习十分有帮助。

   Socket通讯实现参考标准的流程如图所示,

·

  服务器工作:

  1.创建Socket套接字,绑定指定host,并监听。

2.线程堵塞等待用户端请求,当客户端请求到达时建立连接。

  3.连接建立完成后,读取请求并处理,然后将处理结果返回给客户端。

  4. 服务器等待客户端关闭连接,连接关闭后,一次Socket通讯结束。

客户端工作:

   1.创建Socket套接字, 建立连接,发送连接请求数据

2. 请求成功后,等待服务器返回响应

3.服务器回应成功后,处理数据,直到主动关闭连接。

  了解了上述Socket通讯的主要过程,在结合C#网络编程的特性,就可以实现如下C/S服务器。客户端的实现比较简单,主要分四个步骤:

  1.建立tcp连接(等同于socket 和 connect),处理连接失败状态

2.对于建立成功的连接,发送数据,并等待服务器返回

3.接收数据,输出到编辑框

4.关闭连接

private void button1_Click(object sender, EventArgs e)
{
try
{
string s_ipaddress0 = textBox1.Text;
string s_ipaddress1 = textBox2.Text;
string s_ipaddress2 = textBox3.Text;
string s_ipaddress3 = textBox4.Text;
string s_port = textBox5.Text; //限定port的合法性
bool isPort;
int port;
isPort = Int32.TryParse(s_port, out port);
if (!(isPort && port >= && port <= ))
{
OutToClient("Port is Invalid!");
return;
} //限定ip地址的合法性
string host = s_ipaddress0 + "." + s_ipaddress1 + "." + s_ipaddress2 + "." + s_ipaddress3;
if (!IsIpAdress(host))
{
OutToClient("IpAdress is invaild!");
return;
}
IPAddress ip = IPAddress.Parse(host);
IPEndPoint ipe = new IPEndPoint(ip, port); //Ip端口绑定 如192.168.1.48:80 //发送框不能为空, 不然会导致GetBytes出错
if (textBox6.Text == "")
{
OutToClient("Send Text is empty!");
return;
} OutToClient("Conneting..."); int timeout = ; //tcpClient连接到指定端口,并处理超时
TcpClient NetworkClient = TimeOutSocket.Connect(ipe, timeout);
NetworkStream ntwStream = NetworkClient.GetStream();
if (!ntwStream.CanWrite)
{
OutToClient("Data can not be write!");
return;
} //向绑定地址端口发送数据
OutToClient("Client send:" + textBox6.Text);
string sendStr = textBox6.Text;
byte[] by_send = Encoding.ASCII.GetBytes(sendStr);
ntwStream.Write(by_send, , by_send.Length); //等待服务器端返回数据
string recvStr = "";
byte[] recvBytes = new byte[];
int bytes = ntwStream.Read(recvBytes, , recvBytes.Length); //将接收到数据转发输出到Client编辑框
recvStr += Encoding.ASCII.GetString(recvBytes, , bytes);
OutToClient(recvStr); //关闭连接, 一次发送完成
ntwStream.Close();
NetworkClient.Close();
OutToClient("Conneting Close!\r\n");
}
catch (ArgumentNullException ii)
{
OutToClient("ArgumentNullException: "+ ii);
}
catch (SocketException ii)
{
OutToClient("Socket failed! ");
}
catch (Exception ii)
{
OutToClient("Conneting faild!" + ii);
}
}

  服务器内的代码涉及到的知识多一些

1.通过按键1开辟监听线程,用于接收

2.监听线程创建Socket套接字,绑定到指定端口并监听

3.监听线程堵塞在等带连接建立

4.连接建立后监听线程读取客户端数据并回送给客户端处理后数据,然后循环堵塞在连接建立

5.通过按键2删除Socket套接字触发异常,结束线程

按照上述的流程,程序如下:

//新建线程 开始监听
private void button1_Click(object sender, EventArgs e)
{
try
{
isConnectExit = false;
button1.Enabled = false;
button2.Enabled = true; Thread Listen_thread = new Thread(ListenClientConnect);
Listen_thread.IsBackground = true;
Listen_thread.Start();
}
catch (Exception ii)
{
OutToServer("Connet faild!" + ii);
}
}
//监听线程 主要处理数据接收发送
private void ListenClientConnect(object obj)
{
string s_ipaddress0 = textBox1.Text;
string s_ipaddress1 = textBox2.Text;
string s_ipaddress2 = textBox3.Text;
string s_ipaddress3 = textBox4.Text;
string s_port = textBox5.Text; //限定port的合法性
bool isPort;
int port;
isPort = Int32.TryParse(s_port, out port);
if (!(isPort && port >= && port <= ))
{
OutToServer("Port is Invalid!");
return;
} //限定ip地址的合法性
string host = s_ipaddress0 + "." + s_ipaddress1 + "." + s_ipaddress2 + "." + s_ipaddress3;
if (!IsIpAdress(host))
{
OutToServer("IpAdress is invaild!");
return;
} IPAddress ip = IPAddress.Parse(host);
IPEndPoint ipe = new IPEndPoint(ip, port); //新建socket通讯 绑定指定IP+Port 并监听
server_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server_socket.Bind(ipe);
server_socket.Listen(); OutToServer("wait for connect...");
while (isConnectExit == false)
{
Socket CurrentSocket;
try
{
//等待连接 完成三次握手
CurrentSocket = server_socket.Accept();
if(isConnectExit == true)
{
CurrentSocket.Close(); // 关闭Socket
server_socket.Close();
break;
}
OutToServer("Get a Connect!");
ServerProcess(CurrentSocket);
}
catch
{
OutToServer("Connet exti!");
}
}
}
//断开连接
private void button2_Click(object sender, EventArgs e)
{
isConnectExit = true;
button2.Enabled = false;
button1.Enabled = true;
if (server_socket != null)
{
server_socket.Close();
}
}

如此就完成了简单的C/S服务器功能。

实际测试界面如下:

具体源码参考:C/S架构客户端-服务器下载

备注:本程序仅用于演示TCP socket通信流程,服务器端能够监听的IP地址只有本机IP或者127.x.x.1(环回地址), 端口不能为80(和本机http端口冲突)。

TCP/IP协议学习(五) 基于C# Socket的C/S模型的更多相关文章

  1. TCP/IP协议学习(四) 基于C# Socket的Web服务器---静态资源处理

    目录 1. C# Socket通讯 2. HTTP 解析引擎 3. 资源读取和返回 4. 服务器测试和代码下载 Web服务器是Web资源的宿主,它需要处理用户端浏览器的请求,并指定对应的Web资源返回 ...

  2. TCP/IP协议学习(七) 基于C# Socket的Web服务器---动态通讯实现

    目录 (1).基于Ajax的前端实现 (2).Web服务器后端处理 一个完整的web服务器,不仅需要满足用户端对于图片.文档等资源的需求:还能够对于用户端的动态请求,返回指定程序生成的数据.支持动态请 ...

  3. TCP/IP协议学习之实例ping命令学习笔记

    TCP/IP协议学习之实例ping命令学习笔记(一) 一. 目的为了让网络协议学习更有效果,在真实网络上进行ping命令前相关知识的学习,暂时不管DNS,在内网中,进行2台主机间的ping命令的整个详 ...

  4. TCP/IP协议学习(四) 协议概述

    生活中有舒适区,借口成为懒惰的护身符,学习也有舒适区,逃避便是阻止进步的最大障碍. 经过半年多嵌入式方面的工作和学习,我提高了很多,但同时我也对自己所面临的问题逐渐清晰: 1. 偏于实践,理论基础不牢 ...

  5. tcp/ip协议学习笔记一

    一. 简述 以前在学校学习计算机网络的时候学习多是网络7层模型OSI,了解了一些基本的计算机网络概念和协议通信格式,但是一直没弄明白其中的原理,包括各层之间的关系,应用,还有一些常见的令牌环网到底是什 ...

  6. TCP/IP协议学习笔记

    计算机网络基础知识复习汇总:计算机网络基础知识复习 HTTP协议的解析:剖析 HTTP 协议 一个系列的解析文章: TCP/IP详解学习笔记(1)-- 概述 TCP/IP详解学习笔记(2)-- 数据链 ...

  7. TCP/IP协议学习-1.概述

    目录 TCP/IP协议概述 分层 延伸知识 FTP例子 为什么需要网络层和传输层 TCP/IP的分层 封装 分用 总结 本文主要摘抄自书籍<TCP/IP详解卷一:协议>与TCP协议相关内容 ...

  8. TCP/IP协议学习和理解

    TCP:Transmission Control Protocol-传输控制协议 IP:Internet Protocol-网络协议 TCP/IP 不是一个协议,而是一个协议族的统称,里面包括了 IP ...

  9. TCP/IP协议学习

    计算机网路学得不好,首先先放个OSI七层网络模型吧 在协议的控制下,上层对下层进行调用,下层对上层进行服务, 上下层间用交换原语交换信息.这样可以提高传输速率,并且保证数据安全,所以说其实每一层都有存 ...

随机推荐

  1. 变量的解构赋值////////////z

    变量的解构赋值 数组的解构赋值 对象的解构赋值 字符串的解构赋值 数值和布尔值的解构赋值 函数参数的解构赋值 圆括号问题 用途 数组的解构赋值 基本用法 ES6允许按照一定模式,从数组和对象中提取值, ...

  2. Windows Phone 十八、加速计

    加速度传感器 手机的加速度传感器工作时是通过 x.y.z 三个轴的偏移来计算的 在代码基本的 API 主要集中在 Accelerometer 类型中 主要是使用该类型的对象捕获 ReadingChan ...

  3. win7,安装node失败

    win7下,下载node安装包,安装之后 打开命令行输入 node -v,仍然提示命令不可用. 解决办法: 找到环境变量: 在用户变量里修改 path: 添加系统变量 NODE_PATH: 关机重启电 ...

  4. 227 Entering Passive Mode (xxx,xxx,,xxx,xxx,x)

    登录ftp时显示227 Entering Passive Mode (xxx,xxx,,xxx,xxx,x) 因为FTP有两种工作模式,PORT方式和PASV方式,中文意思为主动式和被动式 ,详细介绍 ...

  5. css3动画之小牛奔跑

    今天突然看到阿里云官网的一个悬浮效果挺炫的,就想知道到底是怎么做的,研究了半天,加了一个技术群,原来是css3做的,然后做了一个小 Demo记录下来: <!DOCTYPE html> &l ...

  6. apiCloud又拍云数据库操作经验

    1.在数据库表中有个relation字段,表示一对多(对应其他表的多个记录),这个字段比较奇怪,因为实际上这个字段里并未保存实际值.而是保存在对应表的字段中.但是对应表显示出来并没有这个字段.导出数据 ...

  7. aspose words 介绍

    Aspose.Words是一个商业.NET类库,可以使得应用程序处理大量的文件任务.Aspose.Words支持Doc,Docx,RTF,HTML,OpenDocument,PDF,XPS,EPUB和 ...

  8. Java读取文件最后两行

    File f=new File("C:\\123.txt"); BufferedReader br = new BufferedReader(new FileReader(f)); ...

  9. CountDownLatch和CyclicBarrier 举例详解

    有时候会有这样的需求,多个线程同时工作,然后其中几个可以随意并发执行,但有一个线程需要等其他线程工作结束后,才能开始.举个例子,开启多个线程分块下载一个大文件,每个线程只下载固定的一截,最后由另外一个 ...

  10. SeleniumIDE从0到1 (Selenium IDE 录制)

    seleniumIDE安装成功后下面我们用百度网址来简单录制下: 简介一:百度输入框录制操作 1.打开SeleniumIDE 2.SeleniumIDE地址栏中输入百度网址:[https://www. ...