利用socket以及多线程、文件流等方法实现通信,互发文本信息以及文件
服务器端:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms; namespace 通讯程序再写一次
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Socket socketListen;
private void btnListen_Click(object sender, EventArgs e)
{
try
{
//创建监听socket
socketListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//获取ip
IPAddress ip = IPAddress.Parse(txtIP.Text);
//获取端口号
IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPoint.Text));
//将负责监听的socket绑定这个端口号
socketListen.Bind(point);
ShowMsg("开始监听!");
//设置监听队列,就是在同一时间允许连接的端口数量
socketListen.Listen(10);
//创建一个新线程来执行这个一直在监听中的方法
Thread th = new Thread(Listen);
th.IsBackground = true;
th.Start();
}
catch { }; }
/// <summary>
/// 调用这个方法时把相关内容打印到文本框中
/// </summary>
/// <param name="str"></param>
void ShowMsg(string str)
{
txtRecive.AppendText(str + "\r\n");
}
//创建一个dictionary集合用来存储连入的端口号,以ip名为键,socket为值
Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();
void Listen()
{
while (true)
{
try
{
//负责监听的socket在接收到客户端的连接之后 创建一个负责通信的socket来接收
socketSend = socketListen.Accept();
//如果接收成功 就把发送端的地址显现出来
ShowMsg(socketSend.RemoteEndPoint.ToString() + "连接成功!");
dicSocket.Add(socketSend.RemoteEndPoint.ToString(), socketSend);
//将连入的ip加入listbox里面
pointList.Items.Add(socketSend.RemoteEndPoint.ToString());
//一直接收客户端发来的信息
//需要开启一个新线程
Thread th = new Thread(Recive);
th.IsBackground = true;
th.Start();
}
catch { };
}
}
Socket socketSend;
/// <summary>
/// 接收客户端发来的信息
/// </summary>
void Recive()
{
while (true)
{
try
{
byte[] buffer = new byte[1024 * 1024 * 5];
int r = socketSend.Receive(buffer);
if (r == 0)
{
break;
}
string reciveTxt = Encoding.UTF8.GetString(buffer, 0, r);
ShowMsg(socketSend.RemoteEndPoint + ":" + reciveTxt);
}
catch
{
MessageBox.Show("对方关闭了连接");
break;
}
}
} private void Form1_Load(object sender, EventArgs e)
{
Control.CheckForIllegalCrossThreadCalls = false;
}
/// <summary>
/// 发送文本框中的信息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSend_Click(object sender, EventArgs e)
{ string str = txtSend.Text;
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
//创建一个list泛型集合装进buffer数组,这样可以在字节前面加个我们规定的协议
//比如说这里0为发送文本消息,1为发送文件
List<byte> list = new List<byte>();
//首先这里先把0添加进去,放在第一位,发过去之后再由接收端判断是什么文件,那边再解析
list.Add(0);
list.AddRange(buffer);
//再把集合转化成字节数组,list集合里装的是什么类型的数组,那返回的就是什么类型的数组
byte[] newBuffer = list.ToArray(); //得到listbox里面选中的ip作为键,在dictionary里面找出对应的端口号,发送信息
//刚刚试了一下,如果没选的话,返回空,系统抛异常
try
{
string ip = pointList.SelectedItem.ToString();
dicSocket[ip].Send(newBuffer);
}
catch
{
MessageBox.Show("请选择要发送的ip");
}
//socketSend.Send(buffer);
} private void button1_Click(object sender, EventArgs e)
{
//打开选择文件对话框
OpenFileDialog ofd = new OpenFileDialog();
//对话框名字
ofd.Title = "请选择你的文件";
//设定弹出的初始文件夹路径
ofd.InitialDirectory = @"F:\程序测试文件夹";
//设定好要选择的文件类型
ofd.Filter = "所有文件|*.*";
//弹出对话框
ofd.ShowDialog();
//获得文件所选文件的全路径
string path = ofd.FileName;
//把这个全路径先放进文本框里
txtPath.Text = path; } private void btnSendFile_Click(object sender, EventArgs e)
{
//创建一个string类型的路径来存已经选好路径的文本框里的内容
string path = txtPath.Text;
//用文件流来操作文件
using (FileStream fsRead = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Read))
{
//创建字节数组并规定单次接收长度
byte[] buffer = new byte[1024 * 1024 * 5];
//按照规定的方式读取并且接收他的单次实际读取到的长度
int r = fsRead.Read(buffer, 0, buffer.Length);
List<byte> list = new List<byte>();
//同样方法,标记 1,为文件
list.Add(1);
list.AddRange(buffer);
byte[] newBuffer = list.ToArray();
dicSocket[pointList.SelectedItem.ToString()].Send(newBuffer, 0, r + 1,SocketFlags.None); }
}
}
}

客户端:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms; namespace 客户端
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
Socket socketLink;
private void btnLink_Click(object sender, EventArgs e)
{
try
{
socketLink = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse(txtIP.Text);
IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPoint.Text));
socketLink.Connect(point);
ShowMsg("连接成功!"); Thread th = new Thread(Recive);
th.IsBackground = true;
th.Start();
}
catch { };
}
/// <summary>
/// 传入需要显示在文本框中的内容
/// </summary>
/// <param name="str"></param>
void ShowMsg(string str)
{
txtRecive.AppendText(str + "\r\n");
} void Recive()
{
while (true)
{
try
{
//设定一个字节数组,并规定它的长度
byte[] buffer = new byte[1024 * 1024 * 5];
//接收通过socketLink传过来的字节,存进buffer里,并获取这个字节数组的长度
int r = socketLink.Receive(buffer);
//获取这个字节数组第一位的数字,就是我们规定好的协议,来判断发过来的是消息还是文件
int n = buffer[0];
if (r == 0)
{
break;
}
//如果n==0的话就说明发过来的是文字消息
if (n == 0)
{
string reciveTxt = Encoding.UTF8.GetString(buffer, 1, r - 1);
ShowMsg(socketLink.RemoteEndPoint + ":" + reciveTxt);
}
else if (n == 1)
{
//弹出保存文件的对话框,对接收来的字节数组进行保存
SaveFileDialog sfd = new SaveFileDialog();
sfd.Title = "请选择你要保存的路径";
sfd.InitialDirectory = @"F:\程序测试文件夹";
sfd.Filter = "所有文件|*.*";
//由于版本问题,这里要加this才会弹出保存文件的对话框
sfd.ShowDialog(this);
string path = sfd.FileName;
using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
{
fsWrite.Write(buffer, 1, r - 1);
}
ShowMsg("保存成功");
}
}
catch
{
MessageBox.Show("服务器已关闭");
break;
}
}
} /// <summary>
/// 在程序启动时
/// 不让程序报异常:关于子线程持续调用主线程的内容,跳过
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form2_Load(object sender, EventArgs e)
{
Control.CheckForIllegalCrossThreadCalls = false;
}
/// <summary>
/// 点击按钮发送文本框里的信息给socket通讯
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSend_Click(object sender, EventArgs e)
{
string str = txtSend.Text;
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
socketLink.Send(buffer);
}
}
}

利用socket以及多线程、文件流等方法实现通信,互发文本信息以及文件的更多相关文章
- C#远程获取图片文件流的方法【很通用】
因为之前写的代码,也能获取到图片流信息,但是会是凌乱的线条,后百度得这个方法,必须记录一下 C# try { WebRequest myrequest = WebRequest.Create(Http ...
- C#文件流写入方法
stream为服务端接收的文件流 var bytes = new byte[stream.Length]; stream.Read(bytes, 0, bytes.Length); // 设置当前流的 ...
- 根据上传的MultipartFile通过springboot转化为File类型并调用通过File文件流的方法上传特定服务器
@PostMapping("uploadExcel") public ResponseObj uploadExcel(@RequestParam("excelFile ...
- web api 如何通过接收文件流的方式,接收客户端及前端上传的文件
服务端接收文件流代码: public async Task<HttpResponseMessage> ReceiveFileByStream() { var stream = HttpCo ...
- android中利用Socket实现手机客户端与PC端进行通信
1. 项目截图
- Filezilla FTP Server 设置帐号主目录文件夹的方法和多个帐号共享一个文件夹的方法
1.点击用户头像进入 2.共享文件夹 3.添加共享文件夹 4.设置一个主目录 5.右键主目录 如图6设置别名,别名问主目录路径+别名名称 如:主目录[d:\pro\home\] 别名[aliases1 ...
- 文件寄生——寻找宿主的不归路(NTFS文件流实际应用)
咱们今天来研究下NTFS文件流: NTFS文件系统实现了多文件流特性,NTFS环境一个文件默认使用的是未命名的文件流,同时可创建其他命名的文件流,windows资源管理器默认不显示出文件的命名文件流, ...
- C++文件流类与文件流对象
文件流是以外存文件为输入输出对象的数据流.输出文件流是从内存流向外存文件的数据,输入文件流是从外存文件流向内存的数据.每一个文件流都有一个内存缓冲区与之对应. 请区分文件流与文件的概念,不用误以为文件 ...
- C# IO操作(四)大文件拷贝(文件流的使用)、文件编码
大文件拷贝(文件流的使用).文件编码 首先说一下大文件拷贝和文件流,因为计算机的内存资源是有限的,面对几个G甚至更大的文件,需要通过程序来完成拷贝,就需要用到文件流(因为我们无法做到把文件一 ...
- .net 流(Stream) - 文件流、内存流、网络流
转自:http://www.oseye.net/user/kevin/blog/85 一.文件流 FileStream FileStream流继承与Stream类,一个FileStream类的实例实际 ...
随机推荐
- Redis 如何批量设置过期时间?PIPLINE的使用
合理的使用缓存策略对开发同学来讲,就好像孙悟空习得自在极意功一般~ 抛出问题 Redis如何批量设置过期时间呢? 不要说在foreach中通过set()函数批量设置过期时间 给出方案 我们引入redi ...
- 一次SQL调优 聊一聊 SQLSERVER 数据页
一:背景 1.讲故事 最近给一位朋友做 SQL 慢语句 优化,花了些时间调优,遗憾的是 SQLSERVER 非源码公开,玩起来不是那么顺利,不过从这次经历中我觉得明年的一个重大任务就是好好研究一下它, ...
- 增强MybatisPlus拓展新功能 实战MybatisPlus大合集
mybatis-plus-max简介 MybatisPlusMax是MybatisPlus的增强包,秉承只拓展不修改的理念,对MybatisPlus做增强. 正如MybatisPlus是对MyBati ...
- 序列化框架-Kyro简述
网上有很多资料说 Kryo 只能在 Java 上使用,这点是不对的,事实上除 Java 外,Scala 和 Kotlin 这些基于 JVM 的语言同样可以使用 Kryo 实现序列化. 1.使用方法 ( ...
- Python博客导航
第一部分 - Python程序设计基础 第一章 - Python介绍 1.1 - Python简介 1.2 - Python准备 1.2 - 创建虚拟环境 第二章 - Python基础(建设中) 2. ...
- 你知道这个提高 Java 单元测试效率的 IDEA 插件吗
前言 2023年我们公司主抓代码质量,所以单元测试必不可少,而且都写到了年底的绩效目标中了.在考虑如何达成这个目标的过程中,我发现了一个关于单元测试的IDEA插件--SquareTest,它可以帮助我 ...
- Keepalived高可用集群部署
KeepAlived 目录 KeepAlived KeepAlived安装 KeepAlived部署 准备工作 主备模式 节点配置 验证 正常状态 故障 故障恢复 1+N(一主多备)模式 节点配置 验 ...
- (原创)【B4A】一步一步入门01:简介、开发环境搭建、HelloWorld
一.前言 作者注:絮絮叨叨,可跳过不看. 一直有开发跨平台软件的需求.因为我的主力是C# ,所以当MAUI出现后,我欣喜若狂的开始学习研究.但是经历了两个月左右的时间,我弃坑了,我发现MAUI不是我能 ...
- 如何通过Java应用程序添加或删除 PDF 中的附件
当我们在制作PDF文件或者PPT演示文稿的时候,为了让自己的文件更全面详细,就会在文件中添加附件.并且将相关文档附加到 PDF 可以方便文档的集中管理和传输.那么如何添加或删除 PDF 中的附件呢?别 ...
- 【Azure Cache for Redis】Python Djange-Redis连接Azure Redis服务遇上(104, 'Connection reset by peer')
问题描述 使用Python连接Azure Redis服务,因为在代码中使用的是Djange-redis组件,所以通过如下的配置连接到Azure Redis服务: CACHES = { "de ...