一:由于在上一个随笔的基础之上拓展的所以直接上代码,客户端:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.IO; namespace client
{
public partial class Client : Form
{
public Client()
{
InitializeComponent(); }
//创建 1个客户端套接字 和1个负责监听服务端请求的线程
Socket socketClient = null;
Thread threadClient = null;
private delegate void SetText(string text);
/// <summary>
/// 链接服务端
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_login_Click(object sender, EventArgs e)
{
socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//这里的ip地址,端口号都是服务端绑定的相关数据。
IPAddress ip = IPAddress.Parse(tb_ip.Text.Trim());
IPEndPoint endpoint = new IPEndPoint(ip, Convert.ToInt32(tb_socket.Text.Trim()));
socketClient.Connect(endpoint);//链接有端口号与IP地址确定服务端. ThreadStart thS = new ThreadStart(this.ReceMsg); //客户端在接受服务端发送过来的数据是通过Socket 中的Receive方法,
//该方法会阻断线程,所以我们自己为该方法创建了一个线程
threadClient = new Thread(thS);
threadClient.IsBackground = true;//设置后台线程
threadClient.Start(); }
//接收服务端数据
public void ReceMsg()
{
while (true)//持续监听服务端发来的消息
{
//定义一个2M的内存缓冲区 用于临时性存储接收到的信息
byte[] buffer = new byte[ * * ];
//将客户端套接字接收到的数据存入内存缓冲区, 并获取其长度
int length = socketClient.Receive(buffer);
//clientSocket.Receive(buffer);//接收服务端发送过来的数据
string ReceiveMsg = System.Text.Encoding.UTF8.GetString(buffer,,length);//把接收到的字节数组转成字符串显示在文本框中,如果没有长度,就会以零填充满,后面的日期就会不显示了。
ShowMsg("接收到数据: " + ReceiveMsg);
}
} //消息框里面数据
void ShowMsg(string str)
{
if (this.tb_infor.InvokeRequired)
{
SetText st = new SetText(ShowMsg);
this.Invoke(st, new object[] { str });
}
else
{
//string Ystr = "";
//if (tb_infor.Text != "")
//{
// Ystr = tb_infor.Text + "\r\n";
//}
//tb_infor.Text = Ystr + str + GetCurrentTime();
//代替上面的方法
tb_infor.AppendText(str + GetCurrentTime() + "\r\n");
}
}
/// <summary>
/// 打开文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_openfile_Click(object sender, EventArgs e)
{ if (openFileDialog1.ShowDialog() == DialogResult.OK)//这里需要小括号 ShowDialog()
{
tb_openfile.Text = openFileDialog1.FileName;
}
}
#region
/// <summary>
/// 发送文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_sendfile_Click(object sender, EventArgs e)
{
using (FileStream fs = new FileStream(tb_openfile.Text, FileMode.Open))
{
byte[] buffer = new byte[ * * ];
int readlength = fs.Read(buffer, , buffer.Length);
byte[] filebuffer = new byte[readlength + ];
filebuffer[] = ;
Buffer.BlockCopy(buffer, , filebuffer, , readlength); //第一参数:表示源数组,第二个:表示从源数组中的哪个位置开始拷贝,第三个:表示目标数组。,第四个:表示从目标数组的哪个位置开始填充.,五:表示:拷贝多少数据
socketClient.Send(filebuffer);
}
}
/// <summary>
/// 发送消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_sendmessage_Click(object sender, EventArgs e)
{
string txtMsg = tb_message.Text;
sendmessage(txtMsg); }
/// <summary>
/// 发送信息
/// </summary>
/// <param name="txtMsg"></param>
private void sendmessage(string txtMsg)
{
//将输入的内容字符串转换为机器可以识别的字节数组
byte[] buffer = Encoding.UTF8.GetBytes(txtMsg);
byte[] messagebuffer = new byte[buffer.Length + ];//定义一个新数组,加个标记位,标记是信息
messagebuffer[] = ;//设置标识,表示发送的是字符串
Buffer.BlockCopy(buffer, , messagebuffer, , buffer.Length);//源数组中的数据拷贝到新数组中
socketClient.Send(messagebuffer);
ShowMsg("发送的数据: " + txtMsg); }
#endregion
/// <summary>
/// 获取当前系统时间的方法
/// </summary>
/// <returns>当前时间</returns>
private DateTime GetCurrentTime()
{
DateTime currentTime = new DateTime();
currentTime = DateTime.Now;
return currentTime;
} //快捷键 Enter发送信息
private void tb_message_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{//当光标位于文本框时 如果用户按下了键盘上的Enter键
if (e.KeyCode == Keys.Enter)
{
//则调用客户端向服务端发送信息的方法
sendmessage(tb_message.Text.Trim()); } } }
}

二:服务端

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO; namespace socket
{
public partial class Server : Form
{
public Server()
{
InitializeComponent();
//关闭对文本框的非法线程操作检查,不建议用
//TextBox.CheckForIllegalCrossThreadCalls = false;
} Socket socketWatch = null;//负责监听客户端的套接字
Thread threadWatch = null;//负责监听客户端的线程
Thread threadMoveList = null;//负责去掉失败的socket的ip //声明一个带参数委托处理文本显示
private delegate void SetText(string text);
//声明一个处理ip添加到listbox的委托
private delegate void listboxAdd(string ipsocket);
//声明一个处理在listbox去除ip的委托
private delegate void listboxmove(string ipsocket);
/// 开始服务端监听
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_StartServer_Click(object sender, EventArgs e)
{
#region
//创建一个Socket实例
//第一个参数表示使用ipv4
//第二个参数表示发送的是数据流
//第三个参数表示使用的协议是Tcp协议
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//获取ip地址
IPAddress ip = IPAddress.Parse(tb_ip.Text.Trim());
//创建一个网络通信节点,这个通信节点包含了ip地址,跟端口号。
//这里的端口我们设置为1029,这里设置大于1024,为什么自己查一下端口号范围使用说明。
IPEndPoint endPoint = new IPEndPoint(ip, int.Parse(tb_socket.Text.Trim()));
//设置SOCKET允许多个SOCKET访问同一个本地IP地址和端口号
socketWatch.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
//Socket绑定网路通信节点
socketWatch.Bind(endPoint);
//将套接字的监听队列长度限制为10
socketWatch.Listen(); ShowMsg("开启监听!"); //实力化一个线程上的委托
ThreadStart threadDelegate = new ThreadStart(this.accpet);//还需要invoke
//实力化一个处理线程委托的的新线程
threadWatch = new Thread(threadDelegate);
//等同于上面两句newthread = new Thread(new ThreadStart(this.accpet));
threadWatch.IsBackground = true;
threadWatch.Start();
#endregion
} //消息框里面数据
public void ShowMsg(string str)
{
if (this.tb_infor.InvokeRequired)
{
//实例化一个委托
SetText d = new SetText(ShowMsg);
this.Invoke(d, new object[] { str });
}
else
{ //string Ystr = "";
//if (tb_infor.Text != "")
//{
// Ystr = tb_infor.Text + "\r\n";
//}
//this.tb_infor.Text = Ystr + str + GetCurrentTime();
tb_infor.AppendText(str + GetCurrentTime() + "\r\n");
}
} Dictionary<string, Socket> socketDir = new Dictionary<string, Socket>();//将每一个与客户端进行通信的Socket放到该集合中.
public void accpet()
{
while (true)//注意该循环,服务端要持续监听,要不然一个客户端链接过后就无法链接第二个客户端了。
{ Socket SocketConnection = null;//创建一个负责和客户端通信的套接字
//创建一个接收客户端通信的Socket SocketConnection = socketWatch.Accept();
socketDir.Add(SocketConnection.RemoteEndPoint.ToString(), SocketConnection);//将负责与客户端进行通信的Socket实例添加到集合中。
//如果监听到客户端有链接,则运行到下一部,提示,链接成功!
listboxADD(SocketConnection.RemoteEndPoint.ToString());
ShowMsg("链接成功!");
//创建一个通信线程
ParameterizedThreadStart pts = new ParameterizedThreadStart(ServerRecMsg);
Thread thr = new Thread(pts); //在定义窗体线程的时候,设置线程启动前状态就行了,解决异常
thr.SetApartmentState(ApartmentState.STA); thr.IsBackground = true;
//启动线程
thr.Start(SocketConnection); } }
/// <summary>
/// 在ip栏里添加建立socket的ip
/// </summary>
private void listboxADD(string ipsocket)
{
if (this.ltb_IP.InvokeRequired)
{
listboxAdd list = new listboxAdd(listboxADD);
this.Invoke(list,new object[]{ipsocket});
}
else
{
ltb_IP.Items.Add(ipsocket);
}
} }
/// <summary>
/// 向客户端发送信息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_sendany_Click(object sender, EventArgs e)
{
string SendMsg = tb_message.Text;
if (SendMsg != "")
{
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(SendMsg); //将要发送的数据,生成字节数组。
if (!string.IsNullOrEmpty(this.ltb_IP.Text))
{
string ipendpoint = this.ltb_IP.SelectedItem .ToString();//在服务端,选择与客户端进行通信的IP地址与端口号
socketDir[ipendpoint].Send(buffer);//向客户端发送数据 ShowMsg("向客户端发送了:" + SendMsg);
}
else
{
MessageBox.Show("请选择与哪个客户端进行通信");
} } }
/// <summary>
/// 获取当前系统时间的方法
/// </summary>
/// <returns>当前时间</returns>
private DateTime GetCurrentTime()
{
DateTime currentTime = new DateTime();
currentTime = DateTime.Now;
return currentTime;
} /// <summary>
/// 接收客户端发来的信息
/// </summary>
/// <param name="socketClientPara">客户端套接字对象</param>
private void ServerRecMsg(object socketClientPara)
{
Socket socketServer = socketClientPara as Socket;
while (true)
{
int length = -;
//创建一个内存缓冲区 其大小为1024*1024字节 即1M
byte[] arrServerRecMsg = new byte[ * * ];
try //由于Socket中的Receive方法容易抛出异常,所以我们在这里要捕获异常。
{
//将接收到的信息存入到内存缓冲区,并返回其字节数组的长度
length = socketServer.Receive(arrServerRecMsg);
}
catch (SocketException ex)//注意:在捕获异常时,先确定具体的异常类型。
{
ShowMsg("出现了异常:" + ex.Message);
socketDir.Remove(socketServer.RemoteEndPoint.ToString());//如果出现了异常,将该Socket实例从集合中移除 //ParameterizedThreadStart Delegatemove = new ParameterizedThreadStart(listboxmoveway);//用ParameterizedThreadStart其方法可以带一个object类型的参数
//threadMoveList = new Thread(Delegatemove);
//threadMoveList.IsBackground = true;
//threadMoveList.Start();
//listboxmoveway(socketServer.RemoteEndPoint);//调用方法
//socketServer.Close();
break;//出现异常以后,终止整个循环的执行
}
catch (Exception ex)
{
ShowMsg("出现了异常:" + ex.Message);
break;
}
if (arrServerRecMsg[] == )//表示字符串
{ //将机器接受到的字节数组转换为人可以读懂的字符串
string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, , length-);
//将发送的字符串信息附加到文本框txtMsg上
ShowMsg("接受客户端数据:" + strSRecMsg);
}
else if (arrServerRecMsg[] == )
{
SaveFileDialog savefile=new SaveFileDialog();
if(savefile.ShowDialog()==DialogResult.OK)
{
using(FileStream fs=new FileStream(savefile.FileName,FileMode.Create))
{
fs.Write(arrServerRecMsg, , length - );//将文件写到磁盘上,从1开始到receiveLength-1
ShowMsg("文件写成功!" );
}
} } } } }
}

socket(TCP)发送文件的更多相关文章

  1. 利用Socket远程发送文件

    思想: 1.注意使用两个通道,一个普通对象通信通道,另一个纯净的文件字节流通道 2.利用通信通道发送文件请求,新建字节流通道,开始发送文件

  2. 如何通过Socket TCP发送并接收一个文件?

    一.小结 1.大包发小包收,只发一次. 2.发时把文件扩展名,文件长度也随同一起发送,方便接收端接收时另存为正确的文件类型,并判断是否已经接收完毕. 如果不一起发送,分为文件扩展名,文件长度,文件内容 ...

  3. C# Socket TCP发送图片与接收图片

    如果需要查看更多文章,请微信搜索公众号 csharp编程大全,需要进C#交流群群请加微信z438679770,备注进群, 我邀请你进群! ! ! --------------------------- ...

  4. 使用TCP发送文件

    客户端 package com.zy.demo3; import java.io.File; import java.io.FileInputStream; import java.io.IOExce ...

  5. Java基础---Java---网络编程---TCP、UDP、UDP-键盘录入方式数据、Socket、TCP复制文件、UDP-聊天

    网络编程 网络模型 *OSI参考模型 *Tcp/IP参考模型 网络通读要素 *IP地址 *端口号 *传输协议 1.找到对方Ip 2.数据要发送到对方指定的的应用程序上,为了标识这些应用程序,所经给这些 ...

  6. Socket发送文件

    .Net.cs using System; using System.Collections.Generic; using System.IO; using System.Linq; using Sy ...

  7. Socket传输大文件(发送与接收)

    下载 Client using System; using System.Collections.Generic; using System.Linq; using System.Text; usin ...

  8. {网络编程}和{多线程}应用:基于TCP协议【实现多个客户端发送文件给一个服务器端】--练习

    要求: 实现多个客户端发送文件给一个服务器端 提示:多个人创建客户端发送文件,服务端循环接收socket,从socket中获取文件 说明:这里我们只要建立一个服务端就可以了,然后让多台电脑使用客户端给 ...

  9. Linux C Socket编程发送结构体、文件详解及实例

    利用Socket发送文件.结构体.数字等,是在Socket编程中经常需要用到的.由于Socket只能发送字符串,所以可以使用发送字符串的方式发送文件.结构体.数字等等. 本文:http://www.c ...

随机推荐

  1. 使用java注解的例子有没有

    使用java注解的例子 参考文档:http://www.cnblogs.com/pepcod/archive/2013/02/20/2918719.html http://www.shaoqun.co ...

  2. jquery,javascript -设置某一ul下的li下的 a的属性

    //javascriptvar ul = document.getElementById('ul); var as = ul.getElementsByTagName('a'); for(var i ...

  3. u盘复制提示文件过大

    应该有很多个朋友也遇到过同样的问题,就是我们的u盘的明明可用的空间还有很多,甚至一个空的16g的u盘,但从window等操作系统向u盘拷贝文件的时候,却不能容下诸如iso4g的镜像文件,难道是生产u盘 ...

  4. Missing iOS Distribution signing identity问题解决

    问题描述 打包上传APPStore  Xcode报以下错误:Missing iOS Distribution signing identity for XXXXXX 查看证书后发现,Develop证书 ...

  5. ASP.NET网站实现中英文转换(本地化资源)

    主要内容: 1. 简单例子 2. 进一步认识Localization 3. 语言转换 4. 解决方案 一. 简单例子 下面通过一个简单的例子来说明利用Localization来实现本地化是那么的简单, ...

  6. Error Creating Deployment 有关Tomcat配置问题

    配置Tomcat的时候出现提示框The selected server is enabled,but is not configured properly.Deployment to it will ...

  7. 通用数据挖掘[ZZ]

    一.什么是数据挖掘?许多人认为数据挖掘更像是一门哲学,或数学的组成部分,而不是业务需求的实际解决方案.您可以从采用的各种定义中看出这一点,例如:“数据挖掘是对非常大型的数据进行的研究和分析,采用自动或 ...

  8. 系统默认字体Mac OS,Windows,XP,Lunix

    可查获的信息太少,目前得知的是以中文为例, OS : Helvetical,Lucida Grande(西文默认字体) Windows 7: Microsoft Yahei Xp : Simsun,T ...

  9. 在CMD下用java命令出现“找不到或无法加载主类”问题

    解决思路: 从网上查找原因和解决方法,有提到环境变量classpath设置问题,但多次尝试问题依旧没有解决.然后使用java -cp %classpath; Hello执行,结果正确. 使用echo  ...

  10. PHP 获取目录

    取得当前文件名,当前目录,上层目录 文件名 test.php 路径 + 文件名 (要取得 /var/www/test/test.php)      echo __FILE__; 文件名 (要取得 te ...