Socket是一种通信TCP/IP的通讯接口,也就是HTTP的抽象层,就是Socket在Http之上,Socket也就是发动机。实际上,传输层的TCP是基于网络层的IP协议的,而应用层的HTTP协议又是基于传输层的TCP协议的,而Socket本身不算是协议,就像上面所说,它只是提供了一个针对TCP或者UDP编程的接口。在C#中可以非常方便的使用Socket进行数据传输。

Socket对象是C#使用它的重要对象在Socket的构造函数中,我们可以设置它的地址,Socket的类,支持的协议等等,其定义如下:

public Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType);

我们想要使用Socket,那么就必须创建Socket的对象,创建这个对象,就必须需要IPEndPoint对象来绑定到套接词字中,有如下定义

// 创建负责监听的套接字,注意其中的参数;
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 获得文本框中的IP对象;
IPAddress address = IPAddress.Parse(textBox1.Text.Trim());
// 创建包含ip和端口号的网络节点对象;
IPEndPoint endPoint = new IPEndPoint(address, int.Parse(textBox2.Text.Trim()));

然后再通过Socket的Bind来进行绑定。

socketWatch.Bind(endPoint);

因为我们时刻会被内网中的其他ip和端口进行连接,那么我们就需要创建线程来进行观察,有如下定义

// 设置监听队列的长度;
socketWatch.Listen();
// 创建负责监听的线程;
threadWatch = new Thread(WatchConnecting);
threadWatch.IsBackground = true;
threadWatch.Start();
ShowMsg("服务器启动监听成功!");

其检测方法如下,其中就是不断的去检测客户端的连接请求,通过Accept()方法可以获取一个套接字,然后通过Socket对象的RemoteEndPoint()可以获取一个IP。

void WatchConnecting()
{
while (true) // 持续不断的监听客户端的连接请求;
{
// 开始监听客户端连接请求,Accept方法会阻断当前的线程;
Socket sokConnection = socketWatch.Accept(); // 一旦监听到一个客户端的请求,就返回一个与该客户端通信的 套接字;
// 想列表控件中添加客户端的IP信息;
Online.Items.Add(sokConnection.RemoteEndPoint.ToString());
// 将与客户端连接的 套接字 对象添加到集合中;
dict.Add(sokConnection.RemoteEndPoint.ToString(), sokConnection);
ShowMsg("客户端连接成功!");
Thread thr = new Thread(RecMsg);
thr.IsBackground = true;
thr.Start(sokConnection);
dictThread.Add(sokConnection.RemoteEndPoint.ToString(), thr); // 将新建的线程 添加 到线程的集合中去。
}
}

最后我们开启一个线程去执行RecMsg方法,然后我们不停的去监听客户端给我们的数据发送。

void RecMsg(object sokConnectionparn)
{
Socket sokClient = sokConnectionparn as Socket;
while (true)
{
// 定义一个2M的缓存区;
byte[] arrMsgRec = new byte[ * * ];
// 将接受到的数据存入到输入 arrMsgRec中;
int length = -;
try
{
length = sokClient.Receive(arrMsgRec); // 接收数据,并返回数据的长度;
}
catch (SocketException se)
{
ShowMsg("异常:" + se.Message);
// 从 通信套接字 集合中删除被中断连接的通信套接字;
dict.Remove(sokClient.RemoteEndPoint.ToString());
// 从通信线程集合中删除被中断连接的通信线程对象;
dictThread.Remove(sokClient.RemoteEndPoint.ToString());
// 从列表中移除被中断的连接IP
Online.Items.Remove(sokClient.RemoteEndPoint.ToString());
break;
}
catch (Exception e)
{
ShowMsg("异常:" + e.Message);
// 从 通信套接字 集合中删除被中断连接的通信套接字;
dict.Remove(sokClient.RemoteEndPoint.ToString());
// 从通信线程集合中删除被中断连接的通信线程对象;
dictThread.Remove(sokClient.RemoteEndPoint.ToString());
// 从列表中移除被中断的连接IP
Online.Items.Remove(sokClient.RemoteEndPoint.ToString());
break;
}
if (arrMsgRec[] == ) // 表示接收到的是数据;
{
string strMsg = System.Text.Encoding.UTF8.GetString(arrMsgRec, , length - );// 将接受到的字节数据转化成字符串;
ShowMsg(strMsg);
}
if (arrMsgRec[] == ) // 表示接收到的是文件;
{
SaveFileDialog sfd = new SaveFileDialog(); if (sfd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
{// 在上边的 sfd.ShowDialog() 的括号里边一定要加上 this 否则就不会弹出 另存为 的对话框,而弹出的是本类的其他窗口,,这个一定要注意!!!【解释:加了this的sfd.ShowDialog(this),“另存为”窗口的指针才能被SaveFileDialog的对象调用,若不加thisSaveFileDialog 的对象调用的是本类的其他窗口了,当然不弹出“另存为”窗口。】 string fileSavePath = sfd.FileName;// 获得文件保存的路径;
// 创建文件流,然后根据路径创建文件;
using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))
{
fs.Write(arrMsgRec, , length - );
ShowMsg("文件保存成功:" + fileSavePath);
}
}
}
}
}

我们在方法中获得了一个Object类型的对象,将这个Object对象转换成了Socket,然后我们通过Socket的方法Receive()方法接收返回的数据,其中里面有它的属性,可以获取ip还有一些数据等等。服务器向客户端发送数据也是非常简单。通过Send方法就可以了,如以下定义:

string strMsg = "服务器" + "\r\n" + "   -->" + richTextBox1.Text.Trim() + "\r\n";
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); // 将要发送的字符串转换成Utf-8字节数组;
byte[] arrSendMsg = new byte[arrMsg.Length + ];
arrSendMsg[] = ; // 表示发送的是消息数据
Buffer.BlockCopy(arrMsg, , arrSendMsg, , arrMsg.Length);
string strKey = "";
strKey = Online.Text.Trim();
if (string.IsNullOrEmpty(strKey)) // 判断是不是选择了发送的对象;
{
MessageBox.Show("请选择你要发送的好友!!!");
}
else
{
dict[strKey].Send(arrSendMsg);// 解决了 sokConnection是局部变量,不能再本函数中引用的问题;
ShowMsg(strMsg);
richTextBox1.Clear();
}

最后需要注意的是,如果你的文件较大,有的时候这个缓冲区达不到你的文件字节那么大,那么就会截断,所以与的时候,先将文件转换为Byte是正确的做法。只要在客户端进行逆转就可以了!

C#之Socket的简单使用的更多相关文章

  1. socket.io简单入门(一.实现简单的图表推送)

    引子:随着nodejs蓬勃发展,虽然主要业务系统因为架构健壮性不会选择nodejs座位应用服务器.但是大量的内部系统却可以使用nodejs试水,大量的前端开发人员转入全堆开发也是一个因素. 研究本例主 ...

  2. socket.io简单说明及在线抽奖demo

    socket.io简单说明及在线抽奖demo socket.io 简介 Socket.IO可以实现实时双向的基于事件的通信. 它适用于各种平台,浏览器或设备,也同样注重可靠性和速度. socket.i ...

  3. 运用socket实现简单的服务器客户端交互

    Socket解释: 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. Socket的英文原义是“孔”或“插座”.作为BSD UNIX的进程通信机制,取后一种意 ...

  4. java Socket实现简单在线聊天(二)

    接<java Socket实现简单在线聊天(一)>,在单客户端连接的基础上,这里第二步需要实现多客户端的连接,也就需要使用到线程.每当有一个新的客户端连接上来,服务端便需要新启动一个线程进 ...

  5. java Socket实现简单在线聊天(一)

    最近的项目有一个在线网页交流的需求,由于很久以前做过的demo已经忘记的差不多了,因此便重新学习一下. 我计划的大致实现步骤分这样几大步: 1.使用awt组件和socket实现简单的单客户端向服务端持 ...

  6. Java的Socket通信简单实例

    服务端 package testlxd; import java.io.BufferedReader; import java.io.IOException; import java.io.Input ...

  7. C#中使用Socket实现简单Web服务器

    上一篇博客中介绍了怎样使用socket访问web服务器.关键有两个: 熟悉Socket编程: 熟悉HTTP协议. 上一篇主要是通过socket来模拟浏览器向(任何)Web服务器发送(HTTP)请求,重 ...

  8. Socket通信 简单实现私聊、群聊(dos命令下)

    很久以前的一个Demo,这里服务器只做转发功能,根据ID地址和端口号来标识身份,群聊和私聊只是简单实现, 服务器代码如下: import java.util.*; import java.io.*; ...

  9. C#基于Socket的简单聊天室实践

    序:实现一个基于Socket的简易的聊天室,实现的思路如下: 程序的结构:多个客户端+一个服务端,客户端都是向服务端发送消息,然后服务端转发给所有的客户端,这样形成一个简单的聊天室功能. 实现的细节: ...

  10. Socket的简单使用

    一.Socket: Socket又称”套接字" 网络上的两个程序通过一个双向的通信链接实现数据的交换,这个连接的一端成为一个socket 应用程序通常通过”套接字”向网络发出请求或者应答网络 ...

随机推荐

  1. 【python进阶】深入理解系统进程1

    前言 之前程序执⾏都是⼀条腿⾛路,甚⾄是⽤⼀杆枪来打天下. 通过系统编程的学习,会让⼤家有“多条腿”⼀起⾛路,就好⽐有了⼀把机关枪. 此篇为深入理解进程第一篇,下面开始今天的说明~~~ 进程 多任务的 ...

  2. 【python进阶】深入理解系统进程2

    前言 在上一篇[python进阶]深入理解系统进程1中,我们讲述了多任务的一些概念,多进程的创建,fork等一些问题,这一节我们继续接着讲述系统进程的一些方法及注意点 multiprocessing ...

  3. Flask入门之结构重组(瘦身)-第13讲笔记

    1. pip list Flask 0.10.1 Flask-Bootstrap 3.3.5.6 Flask-SQLAlchemy 2 Flask-Script 2.0.5 Flask-WTF 0.1 ...

  4. swagger上传文件并支持jwt认证

    背景 由于swagger不仅提供了自动实现接口文档的说明而且支持页面调试,告别postman等工具,无需开发人员手动写api文档,缩减开发成本得到大家广泛认可 但是由于swagger没有提供上传文件的 ...

  5. eclipse maven 构建简单springmvc项目

    环境:eclipse Version: Oxygen.3a Release (4.7.3a) 创建maven Project项目,目录结构 修改工程的相关编译属性 修改pop.xml,引入spring ...

  6. 基于Kafka Connect框架DataPipeline在实时数据集成上做了哪些提升?

    在不断满足当前企业客户数据集成需求的同时,DataPipeline也基于Kafka Connect 框架做了很多非常重要的提升. 1. 系统架构层面. DataPipeline引入DataPipeli ...

  7. MySQL 的性能(下篇)—— 性能优化方法

    简介 文中内容均为阅读前辈的文章所整理而来,参考文章已在最后全指明 本文分为上下两篇: 上篇:MySQL 的 SQL 执行分析 下篇:MySQL 性能优化 下面为下篇内容,分为以下部分: 一.创建表时 ...

  8. linux netlink通信机制

    一.什么是Netlink通信机制  Netlink套接字是用以实现用户进程与内核进程通信的一种特殊的进程间通信(IPC) ,也是网络应用程序与内核通信的最常用的接口. Netlink 是一种特殊的 s ...

  9. CentOS下使用命令行Web浏览器Links

    前言: Links是一个运行在命令行模式下的Web浏览器,只能查看字符.Links的官网是Click here. 安装Links yum install links 使用Links links URL ...

  10. Reactor模式的.net版本简单实现--DEMO

    近期在学习DotNetty,遇到不少的问题.由于dotnetty是次netty的.net版本的实现.导致在网上叙述dotnetty的原理,以及实现技巧方面的东西较少,这还是十分恼人的.在此建议学习和使 ...