TCP/IP协议学习(五) 基于C# Socket的C/S模型
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模型的更多相关文章
- TCP/IP协议学习(四) 基于C# Socket的Web服务器---静态资源处理
目录 1. C# Socket通讯 2. HTTP 解析引擎 3. 资源读取和返回 4. 服务器测试和代码下载 Web服务器是Web资源的宿主,它需要处理用户端浏览器的请求,并指定对应的Web资源返回 ...
- TCP/IP协议学习(七) 基于C# Socket的Web服务器---动态通讯实现
目录 (1).基于Ajax的前端实现 (2).Web服务器后端处理 一个完整的web服务器,不仅需要满足用户端对于图片.文档等资源的需求:还能够对于用户端的动态请求,返回指定程序生成的数据.支持动态请 ...
- TCP/IP协议学习之实例ping命令学习笔记
TCP/IP协议学习之实例ping命令学习笔记(一) 一. 目的为了让网络协议学习更有效果,在真实网络上进行ping命令前相关知识的学习,暂时不管DNS,在内网中,进行2台主机间的ping命令的整个详 ...
- TCP/IP协议学习(四) 协议概述
生活中有舒适区,借口成为懒惰的护身符,学习也有舒适区,逃避便是阻止进步的最大障碍. 经过半年多嵌入式方面的工作和学习,我提高了很多,但同时我也对自己所面临的问题逐渐清晰: 1. 偏于实践,理论基础不牢 ...
- tcp/ip协议学习笔记一
一. 简述 以前在学校学习计算机网络的时候学习多是网络7层模型OSI,了解了一些基本的计算机网络概念和协议通信格式,但是一直没弄明白其中的原理,包括各层之间的关系,应用,还有一些常见的令牌环网到底是什 ...
- TCP/IP协议学习笔记
计算机网络基础知识复习汇总:计算机网络基础知识复习 HTTP协议的解析:剖析 HTTP 协议 一个系列的解析文章: TCP/IP详解学习笔记(1)-- 概述 TCP/IP详解学习笔记(2)-- 数据链 ...
- TCP/IP协议学习-1.概述
目录 TCP/IP协议概述 分层 延伸知识 FTP例子 为什么需要网络层和传输层 TCP/IP的分层 封装 分用 总结 本文主要摘抄自书籍<TCP/IP详解卷一:协议>与TCP协议相关内容 ...
- TCP/IP协议学习和理解
TCP:Transmission Control Protocol-传输控制协议 IP:Internet Protocol-网络协议 TCP/IP 不是一个协议,而是一个协议族的统称,里面包括了 IP ...
- TCP/IP协议学习
计算机网路学得不好,首先先放个OSI七层网络模型吧 在协议的控制下,上层对下层进行调用,下层对上层进行服务, 上下层间用交换原语交换信息.这样可以提高传输速率,并且保证数据安全,所以说其实每一层都有存 ...
随机推荐
- 变量的解构赋值////////////z
变量的解构赋值 数组的解构赋值 对象的解构赋值 字符串的解构赋值 数值和布尔值的解构赋值 函数参数的解构赋值 圆括号问题 用途 数组的解构赋值 基本用法 ES6允许按照一定模式,从数组和对象中提取值, ...
- Windows Phone 十八、加速计
加速度传感器 手机的加速度传感器工作时是通过 x.y.z 三个轴的偏移来计算的 在代码基本的 API 主要集中在 Accelerometer 类型中 主要是使用该类型的对象捕获 ReadingChan ...
- win7,安装node失败
win7下,下载node安装包,安装之后 打开命令行输入 node -v,仍然提示命令不可用. 解决办法: 找到环境变量: 在用户变量里修改 path: 添加系统变量 NODE_PATH: 关机重启电 ...
- 227 Entering Passive Mode (xxx,xxx,,xxx,xxx,x)
登录ftp时显示227 Entering Passive Mode (xxx,xxx,,xxx,xxx,x) 因为FTP有两种工作模式,PORT方式和PASV方式,中文意思为主动式和被动式 ,详细介绍 ...
- css3动画之小牛奔跑
今天突然看到阿里云官网的一个悬浮效果挺炫的,就想知道到底是怎么做的,研究了半天,加了一个技术群,原来是css3做的,然后做了一个小 Demo记录下来: <!DOCTYPE html> &l ...
- apiCloud又拍云数据库操作经验
1.在数据库表中有个relation字段,表示一对多(对应其他表的多个记录),这个字段比较奇怪,因为实际上这个字段里并未保存实际值.而是保存在对应表的字段中.但是对应表显示出来并没有这个字段.导出数据 ...
- aspose words 介绍
Aspose.Words是一个商业.NET类库,可以使得应用程序处理大量的文件任务.Aspose.Words支持Doc,Docx,RTF,HTML,OpenDocument,PDF,XPS,EPUB和 ...
- Java读取文件最后两行
File f=new File("C:\\123.txt"); BufferedReader br = new BufferedReader(new FileReader(f)); ...
- CountDownLatch和CyclicBarrier 举例详解
有时候会有这样的需求,多个线程同时工作,然后其中几个可以随意并发执行,但有一个线程需要等其他线程工作结束后,才能开始.举个例子,开启多个线程分块下载一个大文件,每个线程只下载固定的一截,最后由另外一个 ...
- SeleniumIDE从0到1 (Selenium IDE 录制)
seleniumIDE安装成功后下面我们用百度网址来简单录制下: 简介一:百度输入框录制操作 1.打开SeleniumIDE 2.SeleniumIDE地址栏中输入百度网址:[https://www. ...