C#基于Socket的CS模式的完整例子

基于Socket服务器端实现本例主要是建立多客户端与服务器之间的数据传输,首先设计服务器。打开VS2008,在D:\C#\ch17目录下建立名为SocketServer的Windows应用程序。打开工程,往当前窗体中添加控件,如表17-6所示。
表17-6  添加控件列表

控    件

Name

Text

ListBox

lbInfo

 

Label

label

 

Button

button1

启动服务器

设计好的界面如图17-2所示。


接下来开始运用前面的知识设计服务器,主要分为以下步骤。
(1)首先是对一些命名空间的包含,包括System.Net、System.Net.Sockets、System.IO和System.Threading。然后定义一系列的全局变量,如下所示。
 

private Socket s;                                    //定义Socket对象
private Thread th; //客户端连接服务器的线程
public Socket cSocket; //单个客户端连接的Socket对象
public NetworkStream ns; //网络流
public StreamReader sr; //流读取
public StreamWriter sw; //流写入
private delegate void SetTextCallback(); //用于操作主线程控件


(2)接下来是设计客户端连接的管理,主要包括服务器与客户端之间的连接和收发数据问题,把它们放在一个函数Communication里,如下所示。

public void Communication()
{
while (true)
{
try
{
cSocket = s.Accept(); //用cSocket来代表该客户端连接
if (cSocket.Connected) //测试是否连接成功
{
ns = new NetworkStream(cSocket); //建立网络流,便于数据的读取
sr = new StreamReader(ns); //实例化流读取对象
sw = new StreamWriter(ns); //实例化写入流对象
test(); //从流中读取
sw.WriteLine("收到请求,允许连接"); //向流中写入数据
sw.Flush(); //清理缓冲区
}
else
{
MessageBox.Show("连接失败");
}
}
catch (SocketException ex)
{
MessageBox.Show(ex.Message); //捕获Socket异常
}
catch (Exception es)
{
MessageBox.Show("其他异常" + es.Message); //捕获其他异常
}
}
}
//以下代码的用法在第16章有关线程的用法时曾提到过,主要用于从当前线程操作主线程中的控件,这里就不在赘//
public void send()
{
lbInfo.Items.Add(sr.ReadLine()+"\n");
}
public void test()
{
SetTextCallback stcb = new SetTextCallback(send);
Invoke(stcb);
}


 

(3)定义好与客户端的连接后,接下来需要利用线程来启动,双击“启动服务器”按钮,添加如下代码。
 

 button1.Enabled = false;
s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建Socket对象
IPAddress serverIP = IPAddress.Parse("222.18.142.171");
IPEndPoint server = new IPEndPoint(serverIP,13); //实例化服务器的IP和端口
s.Bind(server);
s.Listen(10);
try
{
th = new Thread(new ThreadStart(Communication)); //创建线程
th.Start(); //启动线程
label1.Text = "服务器启动成功!";
}
catch(Exception ex)
{
MessageBox.Show("服务器启动失败!" + ex.Message);
}


(4)最后在关闭服务器窗口的时候,还应该关闭线程和当前Socket连接,代码如下所示。
 

protected override void Dispose(bool disposing)
{
try
{
if (disposing && (components != null))
{
components.Dispose();
th.Abort();
//禁用当前Socket连接中的数据收发
s.Shutdown(System.Net.Sockets.SocketShutdown.Both);
s.Close();
}
base.Dispose(disposing);
}
catch
{
return;
}
}
//接着为当前窗体的FormClosed事件添加如下代码。
this.Close();


至此,服务器就设计完了,下面接着看客户端。
基于Socket客户端实现打开VS2008,在D:\C#\ch17目录下建立名为SocketClient的Windows应用程序。打开工程,往当前窗体中添加控件,如表17-7所示。
表17-7  添加控件列表

控 件 名

Name

Text

GroupBox

groupBox1

向服务器发送消息

Label

label1

发送消息:

TextBox

textBox1

 

Button

button2

发送

ListBox

lbInfo

 

GroupBox

groupBox1

服务器回馈信息


客户端的设计主要分为以下步骤。
(1)首先要做的工作还是要引用一些命名空间,如下所示。

using System.IO; 
using System.Net.Sockets;
using System.Net;

  然后定义一系列的全局变量,如下所示。  

private Socket s;                                         //定义Socket对象                  
public NetworkStream ns; //网络流
public StreamReader sr; //流读取
public StreamWriter sw; //流写入

2)双击“发送”按钮,添加如下代码。

s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverIP = IPAddress.Parse("222.18.142.171"); //服务器IP
try
{
s.Connect(serverIP, 13); //连接服务器,端口号用13
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
try
{
ns = new NetworkStream(s); //实例化网络流
sr = new StreamReader(ns); //实例化流读取对象
sw = new StreamWriter(ns); //实例化写入流对象
sw.WriteLine(textBox1.Text); //将textBox1.Text的数据写入流
sw.Flush(); //清理缓冲区
lbInfo.Items.Add(sr.ReadLine()); //将从流中读取的数据写入lbInfo28 }
catch (Exception ex)
{
MessageBox.Show(ex.Message); //捕获异常
}



(3)最后,关闭Socket连接,释放资源,可以直接在窗体的FormClosed事件中进行,如下所示。
s.Shutdown(SocketShutdown.Both);
s.Close();
至此,服务器和客户端已经全部设计完毕,下面看运行效果。
基于Socket的C/S实例的运行首先,启动服务器程序,单击“启动服务器”按钮,如图17-4所示。接着再启动客户端,并在textBox1输入数据(中英文皆可),多次单击“发送”按钮,如图17-5所示。
此时,服务器的状态如图17-6所示。
收到客户端发送的数据
从图17-6中可以看出,此时服务器已经收到来自客户端的数据,而图17-5中显示客户端也收到了来自服务器的回馈消息。此外,本例还能实现多个客户端向一个服务器同时收发数据,并已经在三台计算机(一个服务器和两个客户端)上测试通过。本例只是实现了服务器与客户端最简单的数据传输,读者如果有兴趣可以在此基础上再添加其他功能,比如可以利用前面讲的数据库知识,在服务器端写个用户登录验证,让客户端通过验证后才能收发数据等。
在网络中,收发数据会经常使用Socket。本节中主要运用了几节中介绍的Socket基础知识完成了一个简单的基于流的C/S模式例子。在下一节中,将介绍另一种传输方式——基于数据报(UDP)。

转载于:https://www.cnblogs.com/wujy/archive/2011/11/22/2259488.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/261143.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java基础之写文件——缓冲区中的多条记录(PrimesToFile3)

控制台程序,上一条博文(PrimesToFile2)每次将一个素数写入到文件中,所以效率不是很高。最好是使用更大的缓冲区并加载多个素数。 本例重复使用三个不同的视图缓冲区加载字节缓冲区并尽可能加入更多的素数,推荐使用这种…

导出oracle sequences,利用数据泵只导出序列

Oracle的数据泵导入导出功能比原有的导入导出工具(exp/imp)功能强很多。利用数据泵我们可以只导出某一特定对象类型,并且可以指定过滤条件。这个功能的实现主要依靠expdp的include参数。联机文档对于参数的功能描述如下:INCLUDEDefault: nonePurposeEnab…

HDU2546_用01背包做

题目大意: 电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额。如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负),否则无…

俄罗斯游戏软件:C语言应用初步感受

俄罗斯游戏软件:C语言应用初步感受C语言课程设以一节课,老师提供了一个C语言的飞俄罗斯方块让我们感受,我们所学的C语言课程,主要是各种语句的练习,这次是用我们所学过的知识来感受一个实际的系统。首先安装c-free&…

重定向 12 21 解析

在 shell 程式中,最常使用的 FD (file descriptor) 大概有三个, 分别是: 0: Standard Input (STDIN) 1: Standard Output (STDOUT) 2: Standard Error Output (STDERR) 在标准情况下, 这些FD分别跟如下设备关联: stdin(0): keyboard 键盘输入,并返回在前端 stdout(…

oracle xml中cdata,XML CDATA的作用

XML CDATA的作用更新时间:2009年09月01日 00:52:36 作者:当你用FLASH和xml结合做网站应用程序时,例如你做在我研究游戏排行榜中,当让人自由输入姓名时,人们可以输入一些符号,例如∶""、"/…

SQL登录 18470 18452 错误

18452,是验证模式没有选择混合模式。 对应方法: 设置允许SQL Server身份登录(基本上这个很有用) 操作步骤: 1。在企业管理器中,展开"SQL Server组",鼠标右键点击SQL Server服务器的名称 2。选择…

android开发(49) android 使用 CollapsingToolbarLayout ,可折叠的顶部导航栏

概述 在很app上都见过 可折叠的顶部导航栏效果。google support v7 提供了 CollapsingToolbarLayout 可以实现这个效果。效果图如下: 实现步骤 1. 写一个 CollapsingToolbarLayout,它有两个 子视图,一个就是上图显示的图片(降落伞…

linux ssh服务端下载文件,Linux SSH服务端配置文件设置

一 SSH概述SSH 由 IETF 的网络小组(Network Working Group)所制定;SSH 为建立在应用层基础上的安全协议。SSH 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。SSH最初是UNIX系统…

注意扩展方法的返回值类型

public static IEnumerable<TSource> Where &#xff1a; IEnumerable<TSource> 类型转载于:https://www.cnblogs.com/changbaishan/p/3391842.html

使用GPUImage实现视频滤镜

关于GPUImage 这里直接引用官方描述&#xff1a;The GPUImage framework is a BSD-licensed iOS library that lets you apply GPU-accelerated filters and other effects to images, live camera video, and movies. In comparison to Core Image (part of iOS 5.0), GPUImag…

C 学习笔记 - 数组

在学习了 C 语言的数组之后&#xff0c;我发现 C 中的数组与 C# 中的数组除了书写形式上略有区别&#xff0c;其它的基本上都一模一样。 因为之前有 C# 的底子&#xff0c;所有学习 C 语言&#xff0c;感觉也挺轻松的&#xff0c;不过 C 和 C# 之前还是有很多不一样的地方&…

yunos5 linux内核,魅蓝5S、魅蓝5对比看差异 选Android还是YunOS?

原标题&#xff1a;魅蓝5S、魅蓝5对比看差异 选Android还是YunOS&#xff1f;几天前魅族发布了魅蓝5S&#xff0c;这款手机刚好2月20日上午10点开始销售&#xff0c;在魅族官方店和天猫都可以买到。作为新一代入门级手机&#xff0c;魅蓝5S最大得卖点恐怕就是加入了18W快充功能…

.net SerialPort

虚拟串口并定时向虚拟串口定时发数据http://scorpiomiracle.iteye.com/blog/653923C#中如何使用SerialPort控件向单片机发送数据&#xff1f;http://zhidao.baidu.com/question/206863745.html?frqrl&index2&qbltopic_question_2_2 转载于:https://www.cnblogs.com/su…

微软ASP.NET站点部署指南(3):使用Web.Config文件的Transformations

1. 综述 大多数程序里都会在Web.config里设置参数&#xff0c;并且在部署的时候需要更改。每次都手工更改这些配置很乏味&#xff0c;也容易出错。该章节将会告诉你如果通过自动化更新Web.config文件来避免这些问题。 2. Web.config Transformations 与Web Deploy Parameters 有…

linux嵌入式c网络编程,嵌入式Linux网络编程之:网络高级编程

本文引用地址&#xff1a;http://www.eepw.com.cn/article/257115.htm在实际情况中&#xff0c;人们往往遇到多个客户端连接服务器端的情况。由于之前介绍的如connet()、recv()和send()等都是阻塞性函数&#xff0c;如果资源没有准备好&#xff0c;则调用该函数的进程将进入睡眠…

myeclipse不编译

错误&#xff1a; org.eclipse.core.internal.registry.configurationElementHandle cannot be cast to org.eclipse.jdt.core.compiler.CompilationParticipant&#xff09; 解决&#xff1a; 关掉MyEclipse>把MyEclipse安装目录下的configuration中的update目录删掉>重…

eclipse配置PHP自动提示代码

为什么80%的码农都做不了架构师&#xff1f;>>> 配置php自动提示代码 &#xff08;html/js和PHP方法一样&#xff09; 1. 打开 Eclipse的 Window -> Preferences -> PHPeclipse -> PHP -> Code Assist 打开里面的Enable auto activation选项,下面有个…

Oracle 执行计划 提示 'PLAN_TABLE' is old version 解决方法

用set autotrace 或者 explain plan for 生成执行计划时&#xff0c;有如下提示&#xff1a;Note----- - PLAN_TABLE is old version导致这个错误的原因是曾经使用toad的执行计划分析过&#xff0c;所以执行了它自带的脚本生成了plan_table。解决办法&#xff0c;drop掉plan_…

C#磁盘遍历——递归

static void Main(string[] args){//创建秒表&#xff0c;记录查询的总时间Stopwatch timer new Stopwatch();timer.Start();//传入本地磁盘路径&#xff0c;遍历当前路径下的所有文件LoadDirectory("G:\传智播客.Net培训—就业班精品");timer.Stop();Console.Write…