C# Socket教程入门,Socket的使用方法,附可执行Demo
核心:
在服务器端和客户端的两个Socket实例,共同维持一个连接,而我们还需要一个服务端绑定了特定端口号的固定的serverSocket,用来监听远方clientSocket的申请,并为这个申请建立服务端对应的proxSocket
服务器维护:
serverSocket
| 服务端实例 | 客户端实例 | 关系 |
|---|---|---|
| proxSocket | clientSocket | 一一对应 |
一、要有服务端
--配置--
1、new Socket
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
2、Bind
ServerSocket.Bind(new IPEndPoint(IPAddress.Parse(txtIP), int.Parse(txtPost))); //服务器绑定本机IP和端口
3、Listen
ServerSocket.Listen(10); //最大连接数是10
4、Accept
Socket proxSocket = ServerSocket.Accept(); //监听Socket连接行为,并为监听到的链接创建Socket实例,会阻塞线程直到端口链接
--信息发送与传输--
5、Receive
proxSocket.Receive(data, 0, data.Length, SocketFlags.None); //data是要写入的byte数组,会阻塞线程直到侦听到slientSocket的Send并持续到IO结束
6、Send
proxSocket.Send(result, 0, result.Length, SocketFlags.None); //result是要上传的byte数组
二、还有客户端
--配置--
1、new Socet
ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
2、Connect
ClientSocket.Connect(new IPEndPoint(IPAddress.Parse(txtIP), int.Parse(txtPort))); //尝试链接服务器的相应IP和端口,连接成功后,服务器端创建一个特定的proxSocket用来进行信息交换
--信息发送与传输--
3
ClientSocket.Receive(data, 0, data.Length, SocketFlags.None);
4
ClientSocket.Send(result, 0, result.Length, SocketFlags.None);
三、简单实现
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace SockerDamo
{
class SocketServer
{
List<Socket> ClientProxSocketList = new List<Socket>();//用于存放客户端链接
Socket ServerSocket { get; set; }
public void Start()//创建服务器Socket,开始侦听客户端,并开始循环接收消息
{
//1.创建socket对象
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ServerSocket = serverSocket;
//first is 寻址方式(此处是Ipv4)
//second is the socket's type
//And the thrid is the 传输协议
System.Console.WriteLine("请输入IP地址:");
String txtIP = Console.ReadLine();
System.Console.WriteLine("请输入端口号:");
String txtPost = Console.ReadLine();
//2.绑定端口IP
ServerSocket.Bind(new IPEndPoint(IPAddress.Parse(txtIP), int.Parse(txtPost)));
//socket's Bind action need a IPEndPoint to bind the socket and the computer's ip and post
//so in the IPEndPoint we need a IPAddress and a int number(Post)
//3.开始侦听
ServerSocket.Listen(20);//the number 表示 同时排队的最大限制数量
//同时来了100个链接请求,只能处理一个链接,队列里面放20个等待链接的客户端,其他的返回错误消息。
//4.开始接受客户端的链接
//为了不阻塞主线程,我们应该把以下代码放在一个新的线程(池)中
try
{
System.Console.WriteLine("开始监听链接...");
Socket proxSocket = ServerSocket.Accept();//这个方法会阻塞当前线程,直到监听到链接
AppendTextToTxtLog(string.Format("客户端{0}已链接", proxSocket.RemoteEndPoint.ToString()));
byte[] data = new byte[1024 * 1024 * 256];//用来放数据的数组
int len;
while (true)
{
System.Console.WriteLine("请选择模式:");
System.Console.WriteLine("0.等待接收消息");
System.Console.WriteLine("1.发送消息");
string mo = Console.ReadLine();
//获取客户端数据并返回读取的字节数,会阻塞当前线程,
//当客户端突然掉线,往往会引发异常
if (mo == "0")
{
try
{
len = proxSocket.Receive(data, 0, data.Length, SocketFlags.None);//往data数组里,从index=0开始,最长写入数据长度为data.Length
if (data[0] == 0)
{
StopConnect(proxSocket);
}//正常退出逻辑
else if (data[0] == 1)
{
string str = Encoding.UTF8.GetString(data, 1, len - 1);//在data数组中从0开始,len个数据,转成str
AppendTextToTxtLog(string.Format("接收到客户端:{0} 的信息是:{1}", proxSocket.RemoteEndPoint.ToString(), str));
}
}
catch (Exception)
{
Console.WriteLine("接收数据出错");
StopConnect(proxSocket);
}
}
else if (mo == "1")
{
SendMsg();
}
}
}
catch
{
AppendTextToTxtLog("出问题啦:您在接收客户端的请求的时候,发生了异常,夭寿啦```");
}
}
private void StopConnect(Socket proxSocket)//停止链接
{
try
{
if (proxSocket.Connected)
{
proxSocket.Shutdown(SocketShutdown.Both);
proxSocket.Close(100);
}
}
catch (Exception ex)
{
System.Console.WriteLine("或许没有成功的停止连接" + ex.ToString());
}
}
//发送消息
private void SendMsg()
{
String txtMsg = Console.ReadLine();
foreach (var proxSocket in ClientProxSocketList)
{
if (proxSocket.Connected)
{
byte[] data = Encoding.UTF8.GetBytes(txtMsg);//信息转二进制
byte[] result = new byte[data.Length + 1];//信息的二进制放在1~data.Length
result[0] = 1;//第0个位置是标志位,将来我们可以用这个标志位,分辨文件类型,将来用来传文件
Buffer.BlockCopy(data, 0, result, 1, data.Length);//把 data从0 转 result从1 长度data.Length
proxSocket.Send(result, 0, result.Length, SocketFlags.None);//发送消息
}
}
AppendTextToTxtLog(string.Format("{0}(本机) 的信息是:{1}", ServerSocket.LocalEndPoint.ToString(), txtMsg));
}
private void AppendTextToTxtLog(string txt)
{
Console.WriteLine(txt);
}
}
class SocketClient
{
Socket ClientSocket { get; set; }
public void Start()//创建客户端Socket,并开始循环接收消息
{
#region 获取服务器端口内容
System.Console.WriteLine("请输入服务器IP:");
String txtIP = Console.ReadLine();
System.Console.WriteLine("请输入端口号:");
String txtPort = Console.ReadLine();
#endregion
//客户端链接服务器端
//1.创建Socket对象
ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//2.连接服务器端Socket
try//如果服务器的Listen队列已满,那么就会返回一个异常
{
ClientSocket.Connect(new IPEndPoint(IPAddress.Parse(txtIP), int.Parse(txtPort)));
}
catch
{
System.Console.WriteLine("当前服务器无法连接");
//Thread.Sleep(1000);
return;
}
//3.接收服务器端消息
byte[] data = new byte[1024 * 1024 * 256];//传输数据放在这里,这里是256MB = 256 * 1024 KB = 256 * 1024 * 1024Byte
int len;
string str;
string wenJianMing = "";
while (true)
{
System.Console.WriteLine("请选择模式:");
System.Console.WriteLine("0.等待接收消息");
System.Console.WriteLine("1.发送消息");
string mo = Console.ReadLine();
len = 0;
str = null;
if (mo == "0")
try
{
len = ClientSocket.Receive(data, 0, data.Length, SocketFlags.None);//获取服务器端数据并返回读取的字节数,会阻塞当前线程,
//当客户端突然掉线,往往会引发异常
if (data[0] == 0)//模式0退出
{
AppendTextToTxtLog(string.Format("服务端:{0} 正常退出", ClientSocket.RemoteEndPoint.ToString()));
StopConnect();
}
else if (data[0] == 1)
{//模式1收到了字符串
str = Encoding.UTF8.GetString(data, 1, len - 1);
AppendTextToTxtLog(string.Format("Socket信息:{0}", str));
}
//一次类推,总共有256种消息的传输模式
}
catch (Exception)
{
AppendTextToTxtLog(string.Format("服务端:{0} 非正常退出",
ClientSocket.RemoteEndPoint.ToString()));
StopConnect();
return;
}
else if(mo == "1"){
SendMsg();
}
}
// 也可以将第3步写入方法ReceiveData
// Thread thread = new Thread(new ParameterizedThreadStart(ReceiveData));
// thread.IsBackground = true;
// thread.Start(); // 然后开启线程
}
private void AppendTextToTxtLog(string txt)
{
Console.WriteLine(txt);
}
private void StopConnect()
{
try
{
if (ClientSocket.Connected)
{
ClientSocket.Shutdown(SocketShutdown.Both);
ClientSocket.Close(100);
}
}
catch (Exception ex)
{
System.Console.WriteLine("或许没有成功的停止连接" + ex.ToString());
}
}
public void SendMsg()
{
if (ClientSocket.Connected)
{
System.Console.WriteLine("请输入要发送信息的模式:");
System.Console.WriteLine("0:结束");
System.Console.WriteLine("1:字符串");
String ms = Console.ReadLine();
if (ms == "0") { }
if (ms == "1")
{
System.Console.WriteLine("请输入要发送的消息:");
String s = Console.ReadLine();
byte[] data = Encoding.UTF8.GetBytes(s);
byte[] result = new byte[data.Length + 1];//信息的二进制放在1~data.Length
result[0] = 1;//第0个位置是标志位,将来我们可以用这个标志位,分辨文件类型,将来用来传文件
Buffer.BlockCopy(data, 0, result, 1, data.Length);//把 data从0 转 result从1 长度data.Length
ClientSocket.Send(result, 0, result.Length, SocketFlags.None);//发送消息
AppendTextToTxtLog(string.Format("本机的信息是:{0}", s));
}
}
}
}
internal class Program
{
static void Main(string[] args)
{
System.Console.WriteLine("0:服务器端");
System.Console.WriteLine("1:客户端");
string ms = Console.ReadLine();
if (ms == "0")
{
SocketServer server = new SocketServer();
server.Start();
}
else if (ms == "1")
{
SocketClient client = new SocketClient();
client.Start();
}
}
}
}
C# Socket教程入门,Socket的使用方法,附可执行Demo的更多相关文章
- 最基础的Python的socket编程入门教程
最基础的Python的socket编程入门教程 本文介绍使用Python进行Socket网络编程,假设读者已经具备了基本的网络编程知识和Python的基本语法知识,本文中的代码如果没有说明则都是运行在 ...
- socket.io入门整理教程
socket.io入门整理 发布于 5 年前 作者 dtrex 124983 次浏览 最后一次编辑是 1 年前 我自己在用socket.io开发,对官方网站上的文档,进行简单的整理,然后自己写 ...
- socket.io 入门教程
转载自:http://deadhorse.me/nodejs/2011/12/29/socket.io_induction.html socket.io socket.io是一个以实现跨浏览器.跨平台 ...
- python socket编程入门(编写server实例)+send 与sendall的区别与使用方法
python 编写server的步骤: 1. 第一步是创建socket对象.调用socket构造函数.如: socket = socket.socket( family, type ) family参 ...
- [ PyQt入门教程 ] PyQt+socket实现远程操作服务器
来需求了..干活啦.. 需求内容 部分时候由于缓存刷新.验证码显示不出来或者浏览器打不开或者打开速度很慢等原因,导致部分测试同事不想使用浏览器登录服务器执行命令.期望有小工具可以替代登录浏览器的操作, ...
- 这可能是最容易入门的socket教程了
前言: 如今,网络编程已然成为了一个后端开发工程师需要具备的核心技能之一.因此,该博客力求提供最简单.通俗的描述方式,来描绘网络编程中常见的知识点,同时附带代码示例,后期会加上具体的抓包分析,实际项目 ...
- Java Socket NIO入门
Java Socket.SocketServer的读写.连接事件监听,都是阻塞式的.Java提供了另外一种非阻塞式读写.连接事件监听方式——NIO.本文简单的介绍一个NIO Socket入门例子,原理 ...
- Socket.io 入门 - Renyi的博客
Socket.io Vue 中使用 NPM 安装 npm install vue-socket.io --save npm install --save socket.io-client 引用 详情 ...
- Node.js、Express、Socket.io 入门
前言 周末断断续续的写了第一个socket.io Demo.初次接触socket.io是从其官网看到的,看着get started做了一遍,根据官网的Demo能提供简单的服务端和客户端通讯. 这个De ...
- Java Socket(1): 入门
前言:在最近一个即将结束的项目中使用到了Socket编程,用于调用另一系统进行处理并返回数据.故把Socket的基础知识总结梳理一遍. 一.TCP/IP协议 既然是网络编程,涉及几个系统之间的交互,那 ...
随机推荐
- 「V 曲闲谈」《宠儿》——谁凌迟着梦想家
反正个人博客啥都能写是吧.( 严格来说,这并不是对歌曲或者 PV 的解析,仅仅是记录这首歌带给我的一些感触. 参考:狐狸座 ver & 艾尔法 ver. 按照简介,歌曲的内容似 ...
- cpa-税法
1.税法总论 2.增值税法 3.消费税法 4.企业所得税法 5.个人所得税法 6.城市维护建设税法和烟叶税法 7.关税法和船舶吨税法 8.资源税法和环境保护税法 9.城镇土地使用税法和耕地占用税法 1 ...
- golang学习链接
GitHub入门: https://github.com/rubyhan1314/Golang-100-Days Golang中国: https://www.qfgolang.com/
- MongoDB:分页查询(统计查询和分页列表查询)、排序查询、正则的复杂条件查询、比较查询、包含查询、条件连接查询
- XposedAPI pg walkthrough Intermediate
nmap ┌──(root㉿kali)-[~/lab] └─# nmap -p- -A 192.168.226.134 Starting Nmap 7.94SVN ( https://nmap.org ...
- Windows下安装和配置Java JDK
1.下载地址 JDK21 Windows安装版下载地址:https://www.oracle.com/java/technologies/downloads/#jdk21-windows JDK21 ...
- Q:windows server2019由于没有远程桌面授权服务器可以提供许可证,远程回话连接已断开
由于没有远程桌面授权服务器可以提供许可证,远程回话连接已断开,请跟服务管理员联系 原因是服务器安装了远程桌面服务RemoteApp,这个是需要授权的.但是微软官方给予了120天免授权使用,超过120天 ...
- 本地部署 DeepSeek Janus Pro 文生图大模型
Hello, 大家新年好. 在这个春节期间最火的显然是 DeepSeek 了.据不负责统计朋友圈每天给我推送关于 DeepSeek 的文章超过20篇.打开知乎跟B站也全是 DeepSeek 相关的内容 ...
- 流程控制之switch选择结构
实现方式:switch case语句 switch case语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支 switch语句中的变量类型可以是: byte.short.int或者cha ...
- kali linux脚本小子速成
$如果你耐心看十分钟,你会惊奇的发现我讲的是一堆废话,别急.kali linux博大精深,绝对不是十分钟就能学的完,真正的好东西永远都是夹在屎里,想学你想要的,拿出你的决心来. kali linux用 ...