服务器端:

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以及多线程、文件流等方法实现通信,互发文本信息以及文件的更多相关文章

  1. C#远程获取图片文件流的方法【很通用】

    因为之前写的代码,也能获取到图片流信息,但是会是凌乱的线条,后百度得这个方法,必须记录一下 C# try { WebRequest myrequest = WebRequest.Create(Http ...

  2. C#文件流写入方法

    stream为服务端接收的文件流 var bytes = new byte[stream.Length]; stream.Read(bytes, 0, bytes.Length); // 设置当前流的 ...

  3. 根据上传的MultipartFile通过springboot转化为File类型并调用通过File文件流的方法上传特定服务器

      @PostMapping("uploadExcel") public ResponseObj uploadExcel(@RequestParam("excelFile ...

  4. web api 如何通过接收文件流的方式,接收客户端及前端上传的文件

    服务端接收文件流代码: public async Task<HttpResponseMessage> ReceiveFileByStream() { var stream = HttpCo ...

  5. android中利用Socket实现手机客户端与PC端进行通信

    1. 项目截图

  6. Filezilla FTP Server 设置帐号主目录文件夹的方法和多个帐号共享一个文件夹的方法

    1.点击用户头像进入 2.共享文件夹 3.添加共享文件夹 4.设置一个主目录 5.右键主目录 如图6设置别名,别名问主目录路径+别名名称 如:主目录[d:\pro\home\] 别名[aliases1 ...

  7. 文件寄生——寻找宿主的不归路(NTFS文件流实际应用)

    咱们今天来研究下NTFS文件流: NTFS文件系统实现了多文件流特性,NTFS环境一个文件默认使用的是未命名的文件流,同时可创建其他命名的文件流,windows资源管理器默认不显示出文件的命名文件流, ...

  8. C++文件流类与文件流对象

    文件流是以外存文件为输入输出对象的数据流.输出文件流是从内存流向外存文件的数据,输入文件流是从外存文件流向内存的数据.每一个文件流都有一个内存缓冲区与之对应. 请区分文件流与文件的概念,不用误以为文件 ...

  9. C# IO操作(四)大文件拷贝(文件流的使用)、文件编码

         大文件拷贝(文件流的使用).文件编码 首先说一下大文件拷贝和文件流,因为计算机的内存资源是有限的,面对几个G甚至更大的文件,需要通过程序来完成拷贝,就需要用到文件流(因为我们无法做到把文件一 ...

  10. .net 流(Stream) - 文件流、内存流、网络流

    转自:http://www.oseye.net/user/kevin/blog/85 一.文件流 FileStream FileStream流继承与Stream类,一个FileStream类的实例实际 ...

随机推荐

  1. C语言读写txt文件

    写入和读取txt文件 #include<stdio.h> #include<string.h> int main( int argc, char *argv[] ) { int ...

  2. prometheus-添加监控linux服务器

    1. prometheus-添加监控linux服务器 prometheus添加监控linux服务器 node_exporter:用于监控Linux系统的指标采集器. 常用指标: CPU 内存 硬盘 网 ...

  3. [随笔所想] UBC学习生活经验分享

    当时受到了很多人的帮助,在网上也查到了很多经验帖子,比如如何办理签证,如何填写表格,要准备哪些材料以及生活上要带哪些物品,等等.当时就想到等我办理好这些,也一定和大家分享,为更多的人提供一些参考. 1 ...

  4. 2_cookie、session、token、sign

    一.关于cookie.session.token.sign 借鉴链接:https://juejin.cn/post/7147913027785293855

  5. 在 C# 9 中使用 foreach 扩展

    在 C# 9 中,foreach 循环可以使用扩展方法.在本文中,我们将通过例子回顾 C# 9 中如何扩展 foreach 循环. 代码演示 下面是一个对树形结构进行深度优先遍历的示例代码: usin ...

  6. java下载网络文件的N种方式

    java下载网络文件的N种方式 通过java api下载网络文件的方法有很多,主要方式有以下几种: 1.使用 common-io库下载文件,需要引入commons-io-2.6.jar public ...

  7. 发布个工具,一键恢复Win8/8.1中的微软拼音长句模式(新体验模式)

    (cnBeta:http://www.cnbeta.com/articles/277936.htm) 首先贴个图,大家来一起念台词~ 念完了木有?很激情澎湃义愤填膺有木有? 这事情最早追溯到前年 8 ...

  8. Web初级——CSS3

    CSS Cascding Style Sheet(层叠级联样式表) 1.前言 1.1CSS优势 内容和表现分离 可以实现CSS代码复用 利用SEO,容易被搜索引擎收录 1.2CSS导入方式 <! ...

  9. YMOI 2019.6.22

    题解 YMOI 2019.6.22 lia麦頔溜了,缺了lia麦頔的排名仅供参考 不过分数还是暴露无遗 T1 邪恶入侵 简易题干: 在三维空间内有一些点,点之间有双向边.每一次询问给出一个m,只有边权 ...

  10. 腾讯出品小程序自动化测试框架【Minium】系列(三)元素定位详解

    写在前面 昨天转发这篇文章时,看到群里有朋友这样说: 这么卷吗?这个框架官方已经不维护了. 姑且不说卷不卷的问题,要是能卷明白,别说还真不错: 不维护又怎样?我想学习,想会,分享给很期待这系列的文章的 ...