socket如何实现传输各种类型的文件?谢谢各位前辈 我用socket类传输文件,代码中将文件转化为binaryReader流,然后上传到服务器端,现在只能传送文本文件,传送别的格式的文件(如视频文件,word文件,音频文件等等)都不能正确转化,哪位兄弟能帮一下小弟,如何实现传各种格式的文件?还有如何在传送文件时将客户端的文件与文件名一起传送到服务器端?小弟先谢了 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 传文件时,(不管什么文件)连接-->发送文件信息(文件名,长度等)-->读数据-->发送文件数据接受时监听-->等待连接-->接受文件信息-->接受文件数据-->写入数据你文件文件能传,其他文件也是一样的.可能是你的edcoding有问题吧. 同意!!把文件转换为btye类型了吗? 传文件时,(不管什么文件) 连接-->发送文件信息(文件名,长度等)-->读数据-->发送文件数据 接受时 监听-->等待连接-->接受文件信息-->接受文件数据-->写入数据 你文件文件能传,其他文件也是一样的.可能是你的edcoding有问题吧.------------------------严重同意! Socket传文件是用二进制流,跟文件类型是没有关系的。 视频音频都可以bytes传输啊。传送结构你可以自己定义啊。比如把文件名加在文件前面。读取时按你传送结构来分别读取就可以了 二进制如C---->S (传送文件类型为Txt)C---->S (开始传送)C---->S (数据传输)C---->S (结束)都用二进制传送,并自己规定好如:000表示 开始传送文件001表示 exe....111表示文件传送结束等等 这是发送端类using System;using System.Drawing;using System.Collections;using System.ComponentModel;using System.Windows.Forms;using System.Net;using System.Net.Sockets;using System.IO;using System.Text;namespace Socket_Demo{ class Socket_Client { public Socket_Client(string remoteIp,int remotePort,string sendFileName) { this.remoteIp=remoteIp; this.remotePort=remotePort; this.sendFileName=sendFileName; } string remoteIp=""; int remotePort=0; string sendFileName=""; System.Net.Sockets.Socket send_Socket; NetworkStream tcpStream; public bool connect_Server() { IPAddress ipAdd=IPAddress.Parse(this.remoteIp); IPEndPoint ipEnd=new IPEndPoint(ipAdd,remotePort); send_Socket = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { send_Socket.Connect(ipEnd); } catch (Exception ex) { MessageBox.Show("连接远程IP错误"+ex.Message,"提示信息",MessageBoxButtons.RetryCancel,MessageBoxIcon.Information); return false; } return true; } public void send_File() { tcpStream = new NetworkStream(send_Socket) ; FileStream fs = new FileStream(sendFileName, FileMode.Open, FileAccess.Read); BinaryReader fileReader = new BinaryReader(fs,Encoding.Default); long Total=fs.Length; byte[] bytes = new byte[Total]; int hasRead=0; int len; //获取要传输文件的总长度 //读取文件写入到数据流中 while((hasRead<=fs.Length)&&tcpStream.CanWrite&&fileReader.Read(bytes,0,bytes.Length)!=0) { //从要传输的文件读取指定长度的数据 len =fileReader.Read(bytes,0,bytes.Length) ; //将读取的数据发送到对应的计算机 tcpStream.Write(bytes,0,hasRead); try { //向主机发送请求 send_Socket.Send(bytes,bytes.Length,0); } catch(Exception ce) { MessageBox.Show("发送错误:"+ce.Message,"提示信息",MessageBoxButtons.RetryCancel,MessageBoxIcon.Information); } //增加已经发送的长度 hasRead+=len ; } fileReader.Close(); fs.Close(); //禁用Socket send_Socket.Shutdown(SocketShutdown.Both); //关闭Socket send_Socket.Close(); } }} 这是接受端类using System;using System.Drawing;using System.Collections;using System.ComponentModel;using System.Windows.Forms;using System.Net;using System.Net.Sockets;using System.Threading;using System.IO;using System.Text;namespace Socket_Server{ class Socket_Recived { public Socket_Recived(string saveFileName, int port) { this.port = port; this.saveFileName = saveFileName; } public Thread thThreadRead; //创建线程,用以侦听端口号,接收信息 public TcpListener tlTcpListen; //侦听端口号 public bool blistener = true; //设定标示位,判断侦听状态 public Socket stRead; int port = 0; string saveFileName = "";//保存的文件名称 public void start_Listen() { thThreadRead = new Thread(new ThreadStart(Listen)); //以Listen过程来初始化Thread实例 thThreadRead.Start(); //启动线程 } private void Listen() { try { IPHostEntry ieh = Dns.GetHostByName(Dns.GetHostName()); IPAddress LocalIP = ieh.AddressList[0]; int LocalPort = port; string ip = LocalIP.ToString(); tlTcpListen = new TcpListener(LocalIP, LocalPort); tlTcpListen.Start(); //开始监听网络的连接请求 stRead = tlTcpListen.AcceptSocket(); //通过连接请求,并获得接收数据时使用的Socket实例 EndPoint tempRemoteEP = stRead.RemoteEndPoint; IPEndPoint tempRemoteIP = (IPEndPoint)tempRemoteEP; //获取请求的远程计算机名称 IPHostEntry host = Dns.GetHostByAddress(tempRemoteIP.Address); string sHostName = host.HostName; //同意和发送端计算机建立连接 string ReceiveContent = ""; string sTime = DateTime.Now.ToShortTimeString(); int iRead; //循环侦听 while (blistener) { Byte[] byRead = new Byte[229888]; iRead = stRead.ReceiveFrom(byRead, ref tempRemoteEP); //读取完成后退出循环 if (iRead <= 0) { //保存数据流为本地文件 byte[] content = Encoding.Default.GetBytes(ReceiveContent); try { //创建文件流对象实例 FileStream fs = new FileStream(saveFileName,FileMode.OpenOrCreate, FileAccess.ReadWrite); //写入文件 fs.Write(content, 0, content.Length); fs.Close(); } catch (Exception fe) { MessageBox.Show("文件创建/写入错误:" + fe.Message, "提示信息", MessageBoxButtons.RetryCancel, MessageBoxIcon.Information); } stRead.Close(); tlTcpListen.Stop(); //关闭侦听 thThreadRead.Abort(); //中止线程 break; } else { //将读取的字节数转换为字符串 ReceiveContent += Encoding.Default.GetString(byRead); ReceiveContent = ReceiveContent.TrimEnd(new char[] { '\0' }); } } } catch (System.Security.SecurityException) { MessageBox.Show("侦听失败!", "错误"); } } }} FileStream fs = new FileStream(sendFileName, FileMode.Open, FileAccess.Read); BinaryReader fileReader = new BinaryReader(fs,Encoding.Default); long Total=fs.Length; byte[] bytes = new byte[Total]; int hasRead=0; int len; 直接用 byte[] bytes = File.ReadAllBytes(sendFileName); 代替.发送长度不要用 文件.length ,而要用 bytes.Length.接收也是如此就行.还用,socket好像有一次发送的长度要求,文件太大了要注意分包. 哦 我找到原因了,发送文件的时候我将文件转换为binaryReader流,读入字节中传递。然后在接收端也要binaryWriter读取接收到的字节就可以了。和上面wdgphc这位兄弟说的意思是一样的。谢谢各位,还有一个问题就是怎么在传送文件的时候将文件名同时发送?如果多个客户端连接一个服务器端发送数据时,我应该怎么做保证数据接收的正确性呢??请教各位前辈了,稍后散分。 你可以这样,定义一个协议结构.比如: 起始位 + 文件名 + 正文开始指示位 + 正文 + 正文结束标识 + MD5验证码 + 结束位接收方也按此解包即可.用MD5将发送串做校验码一并发送,接收方收到后就能解析是否接收正确了. wdgphc大哥,您说的太深奥了,小弟明白不了,您能给个例子吗?还有您说的文件太大时我应该怎么传送?我QQ:406556628,要不您加我可以吗?谢谢 我也正在关注这个问题,那个大侠有好方法,或者 现成的例子的,请发给我[email protected] 不胜感谢。 初学者的迷茫 WPF制作类似Winform中的SplitContainer组建效果 如何调用系统默认文本编辑器打开文本格式文件(非txt) System.IO 文件正由另一进程使用,因此该进程无法访问该文件 求一超简单的正则表达式 求助,c# 中调用POWERPOINT的问题,进者有分 新手提问:关于liseview的问题 c# 200分C#代码生成器源代码 提个很菜的问题,C#和vc.net,vc.net和vc++有什么关系? 高手指教:一个有关GUI+的问题,请进看一看,帮帮小弟 在smartphone中有没有类似button的控件 高分求教!c#如何将字符串转换为数组?
连接-->发送文件信息(文件名,长度等)-->读数据-->发送文件数据接受时
监听-->等待连接-->接受文件信息-->接受文件数据-->写入数据你文件文件能传,其他文件也是一样的.可能是你的edcoding有问题吧.
把文件转换为btye类型了吗?
连接-->发送文件信息(文件名,长度等)-->读数据-->发送文件数据 接受时
监听-->等待连接-->接受文件信息-->接受文件数据-->写入数据 你文件文件能传,其他文件也是一样的.可能是你的edcoding有问题吧.
------------------------
严重同意!
如C---->S (传送文件类型为Txt)
C---->S (开始传送)
C---->S (数据传输)
C---->S (结束)
都用二进制传送,并自己规定好
如:
000表示 开始传送文件
001表示 exe
....
111表示文件传送结束
等等
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Text;namespace Socket_Demo
{
class Socket_Client
{
public Socket_Client(string remoteIp,int remotePort,string sendFileName)
{
this.remoteIp=remoteIp;
this.remotePort=remotePort;
this.sendFileName=sendFileName;
}
string remoteIp="";
int remotePort=0;
string sendFileName="";
System.Net.Sockets.Socket send_Socket;
NetworkStream tcpStream; public bool connect_Server()
{
IPAddress ipAdd=IPAddress.Parse(this.remoteIp);
IPEndPoint ipEnd=new IPEndPoint(ipAdd,remotePort);
send_Socket = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
send_Socket.Connect(ipEnd);
}
catch (Exception ex)
{
MessageBox.Show("连接远程IP错误"+ex.Message,"提示信息",MessageBoxButtons.RetryCancel,MessageBoxIcon.Information);
return false;
}
return true;
}
public void send_File()
{
tcpStream = new NetworkStream(send_Socket) ;
FileStream fs = new FileStream(sendFileName, FileMode.Open, FileAccess.Read);
BinaryReader fileReader = new BinaryReader(fs,Encoding.Default);
long Total=fs.Length;
byte[] bytes = new byte[Total];
int hasRead=0;
int len;
//获取要传输文件的总长度
//读取文件写入到数据流中
while((hasRead<=fs.Length)&&tcpStream.CanWrite&&fileReader.Read(bytes,0,bytes.Length)!=0)
{
//从要传输的文件读取指定长度的数据
len =fileReader.Read(bytes,0,bytes.Length) ;
//将读取的数据发送到对应的计算机
tcpStream.Write(bytes,0,hasRead);
try
{
//向主机发送请求
send_Socket.Send(bytes,bytes.Length,0);
}
catch(Exception ce)
{
MessageBox.Show("发送错误:"+ce.Message,"提示信息",MessageBoxButtons.RetryCancel,MessageBoxIcon.Information);
}
//增加已经发送的长度
hasRead+=len ;
}
fileReader.Close();
fs.Close();
//禁用Socket
send_Socket.Shutdown(SocketShutdown.Both);
//关闭Socket
send_Socket.Close();
}
}
}
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Text;namespace Socket_Server
{
class Socket_Recived
{
public Socket_Recived(string saveFileName, int port)
{
this.port = port;
this.saveFileName = saveFileName;
} public Thread thThreadRead;
//创建线程,用以侦听端口号,接收信息
public TcpListener tlTcpListen;
//侦听端口号
public bool blistener = true;
//设定标示位,判断侦听状态
public Socket stRead;
int port = 0;
string saveFileName = "";//保存的文件名称
public void start_Listen()
{
thThreadRead = new Thread(new ThreadStart(Listen));
//以Listen过程来初始化Thread实例
thThreadRead.Start();
//启动线程
} private void Listen()
{
try
{
IPHostEntry ieh = Dns.GetHostByName(Dns.GetHostName());
IPAddress LocalIP = ieh.AddressList[0];
int LocalPort = port;
string ip = LocalIP.ToString();
tlTcpListen = new TcpListener(LocalIP, LocalPort);
tlTcpListen.Start();
//开始监听网络的连接请求
stRead = tlTcpListen.AcceptSocket();
//通过连接请求,并获得接收数据时使用的Socket实例
EndPoint tempRemoteEP = stRead.RemoteEndPoint;
IPEndPoint tempRemoteIP = (IPEndPoint)tempRemoteEP;
//获取请求的远程计算机名称
IPHostEntry host = Dns.GetHostByAddress(tempRemoteIP.Address);
string sHostName = host.HostName; //同意和发送端计算机建立连接 string ReceiveContent = "";
string sTime = DateTime.Now.ToShortTimeString();
int iRead;
//循环侦听
while (blistener)
{
Byte[] byRead = new Byte[229888];
iRead = stRead.ReceiveFrom(byRead, ref tempRemoteEP); //读取完成后退出循环
if (iRead <= 0)
{
//保存数据流为本地文件
byte[] content = Encoding.Default.GetBytes(ReceiveContent);
try
{
//创建文件流对象实例
FileStream fs = new FileStream(saveFileName,FileMode.OpenOrCreate, FileAccess.ReadWrite);
//写入文件
fs.Write(content, 0, content.Length);
fs.Close();
}
catch (Exception fe)
{
MessageBox.Show("文件创建/写入错误:" + fe.Message, "提示信息", MessageBoxButtons.RetryCancel, MessageBoxIcon.Information);
}
stRead.Close();
tlTcpListen.Stop();
//关闭侦听
thThreadRead.Abort(); //中止线程
break;
}
else
{
//将读取的字节数转换为字符串
ReceiveContent += Encoding.Default.GetString(byRead);
ReceiveContent = ReceiveContent.TrimEnd(new char[] { '\0' });
}
}
}
catch (System.Security.SecurityException)
{
MessageBox.Show("侦听失败!", "错误");
}
}
}
}
BinaryReader fileReader = new BinaryReader(fs,Encoding.Default);
long Total=fs.Length;
byte[] bytes = new byte[Total];
int hasRead=0;
int len; 直接用 byte[] bytes = File.ReadAllBytes(sendFileName); 代替.
发送长度不要用 文件.length ,而要用 bytes.Length.接收也是如此就行.还用,socket好像有一次发送的长度要求,文件太大了要注意分包.
比如: 起始位 + 文件名 + 正文开始指示位 + 正文 + 正文结束标识 + MD5验证码 + 结束位
接收方也按此解包即可.
用MD5将发送串做校验码一并发送,接收方收到后就能解析是否接收正确了.
我也正在关注这个问题,那个大侠有好方法,或者 现成的例子的,请发给我[email protected] 不胜感谢。 初学者的迷茫