socket 异步文件传输 各位大侠, 在与客户端与服务器端的连接中,我用的是一个端口号,这样,在客户端与服务器端连接进行异步通信时,客户端的一个文件传输是没问题的,但要执行多个任务就会有问题了! 我想问一下,是否在同一个端口可以异步执行多个任务呢?急!!!! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 http://www.csharpwin.com/csharpresource/695.shtml 若是TCP,每个任务使用一个连接就没问题了若是UDP,给每个包加上一个ID标识也能解决问题 好像都没有解决问题,我还是把我的代码贴出来吧! 我的程序是控制台的Server:服务器端 static void Main(string[] args) { IPAddress ip = Dns.GetHostByName(Dns.GetHostName()).AddressList[0]; Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); listener.Bind(new IPEndPoint(ip, 1005)); listener.Listen(150); while (true) { Socket socket = listener.Accept(); RemoteClient client = new RemoteClient(socket); client.BeginRead(); } } public RemoteClient(Socket sock) { this.M_socket = sock; Console.WriteLine("Client Connected!{0}<--{1}", sock.LocalEndPoint,sock.RemoteEndPoint); streamToClient = new NetworkStream(sock); //定义缓存大小 buffer = new byte[BufferSize]; } public void BeginRead() { AsyncCallback callBack = new AsyncCallback(OnReadComplete); streamToClient.BeginRead(buffer, 0, BufferSize, callBack, null); } private void OnReadComplete(IAsyncResult ar) { try { bytesRead = streamToClient.EndRead(ar); string message = Encoding.Unicode.GetString(buffer, 0, bytesRead); ParameterizedThreadStart start = new ParameterizedThreadStart(handleProtocol); start.BeginInvoke(pro, null, null); } catch (Exception e) {} } private void handleProtocol(object obj) { string pro = obj as string; receiveFile(pro); } private void receiveFile(string protocol) { string path = @"E:/" + protocol.FileName; byte[] fileBuffer = new byte[BufferSize]; FileInfo file = new FileInfo(path); using (FileStream fs = file.Open(file.Exists ? FileMode.Append : FileMode.CreateNew, FileAccess.Write, FileShare.None)) { try { int bytesRead = M_socket.Receive(fileBuffer); long totalBytes = fs.Length; M_socket.Send(BitConverter.GetBytes(totalBytes)); long length = BitConverter.ToInt64(fileBuffer, 0); while (totalBytes < length) { bytesRead = streamToClient.Read(buffer, 0, BufferSize); fs.Write(buffer, 0, bytesRead); fs.Flush(); totalBytes += (long)bytesRead; Console.WriteLine("Receiving {0} bytes...", totalBytes); } Console.WriteLine("Total {0} bytes received,Done!", totalBytes); } catch (Exception e) { } } } Client客户端: static void Main(string[] args) { RemoteClient Rclient = new RemoteClient(); Console.ReadLine(); } public RemoteClient() { try { ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress ip = Dns.GetHostByName(Dns.GetHostName()).AddressList[0]; ClientSocket.Connect(ip, 1005); } buffer = new byte[BufferSize]; Console.WriteLine("Server Connected!{0}-->{1}", ClientSocket.LocalEndPoint, ClientSocket.RemoteEndPoint); streamToServer = new NetworkStream(ClientSocket); ConsoleKey key; List<string> PathList = new List<string>(); Console.WriteLine("输入上传路径后回车,按G开始执行任务..."); do { Console.WriteLine("请输入上传路径..."); string filePath = Console.ReadLine(); PathList.Add(filePath); key = Console.ReadKey(true).Key; }while(key != ConsoleKey.G); for(int i=0;i<PathList.Count;i++) { if (File.Exists(PathList[i].ToString())) { BeginSendFile(PathList[i].ToString()); } else { Console.WriteLine("此{0}路径无效!",PathList[i].ToString()); } } } public void BeginSendFile(string filePath) { ParameterizedThreadStart start = new ParameterizedThreadStart(SendFile); start.BeginInvoke(filePath, null, null); } private void SendFile(object obj) { string filePath = obj as string; SendFile(filePath); } public void SendFile(string filePath) { IPEndPoint endpoint = ClientSocket.LocalEndPoint as IPEndPoint; int listeningPort = endpoint.Port; string fileName = Path.GetFileName(filePath); NetworkStream stream = new NetworkStream(ClientSocket); // 创建文件流 FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); byte[] fileBuffer = new byte[BufferSize]; Buffer.BlockCopy(BitConverter.GetBytes(fs.Length), 0, fileBuffer, 0, PerLongCount); ClientSocket.Send(fileBuffer, 0, PerLongCount + Encoding.Default.GetBytes(fileName, 0, fileName.Length, fileBuffer, PerLongCount), SocketFlags.None); ClientSocket.Receive(fileBuffer); int bytesRead; long totalBytes; fs.Position = totalBytes = BitConverter.ToInt64(fileBuffer, 0); try { do { Thread.Sleep(20); bytesRead = fs.Read(fileBuffer, 0, fileBuffer.Length); stream.Write(fileBuffer, 0, bytesRead); totalBytes += (long)bytesRead; } while (bytesRead > 0); } catch {} } 主要的代码都在这里了,好了,现在问题来了,在同一个客户端同时执行多个任务却有问题,不知哪位高手可帮小弟看一看,是不是同一个客户端的端口号不支持多任务的异步传输呢? 多线程。建立多个连接 protected override void OnStart(string[] args) { if (ic.g_SendNum>0) { for (int i = 1; i < ic.g_SendNum + 1; i++) { SendThread = new Thread(new ParameterizedThreadStart(SendServer)); SendThread.Start(i); SendThreadListen = new Thread(new ParameterizedThreadStart(ic.SendLinten)); SendThreadListen.Start(ic.iniSend[i]); } } if (ic.g_ReceiveNum>0) { for (int i = 1; i < ic.g_ReceiveNum + 1; i++) { ReceiveThread = new Thread(new ParameterizedThreadStart(ReceiveServer)); ReceiveThread.Start(i); ReceiveThreadListen = new Thread(new ParameterizedThreadStart(ic.ReceiveLinten)); ReceiveThreadListen.Start(ic.iniSend[i]); } } } public void ReceiveServer(Object objct) { int nIndex = (int)objct; IPEndPoint ipep = new IPEndPoint(IPAddress.Any, ic.iniReceive[nIndex].nRecPort); Socket ser = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //绑定网络地址 ser.Bind(ipep); Console.WriteLine("This is a Server,Host name is {0}", Dns.GetHostName()); //等待客户端连接 ic.Log("Waiting for a client..."); ser.Listen(0); EndPoint ipConnect = null; try { Socket newsock = ser.Accept(); ipConnect = ser.RemoteEndPoint; ic.Log("Waited..."); Object oj = newsock as Object; while (true) { ic.Log("开始接收文件 ... "); if (!ic.ReceiveFile(ic.iniReceive[nIndex].strAimPath, newsock, ic.iniReceive[nIndex])) { ic.Log(ipConnect.ToString()+"异常断开,10秒后重新连接"); newsock.Close(); ser.Close(); ReceiveServer(objct); break; } Console.WriteLine("接收完成 ... "); ic.Log("接收完成 ... "); } } catch (Exception e) { ic.Log(ipConnect.ToString() + "连接失败"); string strContent = e.Message.ToString() + Environment.NewLine + e.StackTrace.ToString(); ic.Log(strContent); ic.Log("10秒钟后重新连接"); ser.Close(); ReceiveServer(objct); Thread.Sleep(10 * 1000); } } public void SendServer(Object oj) { int nIndex = (int)oj; byte[] data = new Byte[20 * 1024]; ic.iniSend[nIndex].bDicExist = ic.CreateDirectory(ic.iniDicPath, MyDict); Console.WriteLine("This is a Client, host name is {0}", Dns.GetHostName()); IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(ic.iniSend[nIndex].strIP), ic.iniSend[nIndex].nSendPort); Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ic.Log("Connecting ... "); try { server.Connect(ipep); if (server.Connected) { ic.Log("Connected ... "); while (true) { ic.FileListDict.Clear(); ic.Log("开始遍历 ... "); for (int i = 1; i < ic.iniSend[nIndex].sendnum + 1; i++) { if (Directory.Exists(ic.iniSend[nIndex].strSourcePath[i])) { ic.Log("开始遍历:" + ic.iniSend[nIndex].strSourcePath[i]); if (!ic.FindFile(ic.iniSend[nIndex].strSourcePath[i], server, MyDict, i, ic.iniSend[nIndex])) { ic.Log(ic.iniSend[nIndex].strIP+"遍历失败,10秒后重新遍历"); server.Close(); SendServer(oj); break; } ic.Log(ic.iniSend[nIndex].strSourcePath[i] + " 遍历完成 ... "); } else { ic.Log(ic.iniSend[nIndex].strSourcePath[i] + "路径不存在"); Console.WriteLine("路径不存在"); } } ic.WriteDirectory(ic.iniDicPath, MyDict); CP2PMessage msgEnd = new CP2PMessage(); msgEnd.nMessageTypes = (sbyte)(9); data = Tool.StructToBytes(msgEnd); if (data.Length > 0) server.Send(data, data.Length, 0); Console.WriteLine("遍历完成 ... "); ic.Log("遍历完成 ... "); if (ic.iniSend[nIndex].CompareFile > 120) { ic.iniSend[nIndex].CompareFile = 0; for (int j = 1; j < ic.iniSend[nIndex].sendnum + 1; j++) { ic.FunCompareFile(ic.iniSend[nIndex].strSourcePath[j], server, j, ic.iniSend[nIndex]); } ic.Log("文件匹配完成... "); } Thread.Sleep(10 * 1000); } } else { ic.Log(ic.iniSend[nIndex].strIP + "初始化连接失败,10秒后重新连接"); server.Close(); SendServer(oj); } } catch (Exception e) { ic.Log(ic.iniSend[nIndex].strIP + "连接失败"); string strContent = e.Message.ToString() + Environment.NewLine + e.StackTrace.ToString(); ic.Log(strContent); ic.Log("重新连接"); SendServer(oj); } } 双重for循环写成PadLeft(….)的方法! asp.net如何搭建目录式伪静态? C#关于随机数 打开解决方案出问题了 datagridview 多行表头 ===求教如何实现通过程序读取sql数据库的信息,然后插入acess表中=== 急!!!ORACLE中的LONG类型的字段,C#如何存取? 怎么在一个TextBox里输入数据,另一个TextBox里的数据也跟着改变 求思路,我怎么把以下的htm代码中的table输出一个Excel文件 关于WebBrowser的奇怪问题 c#socket读取数据问题 dropdownlist选中值问题?
若是UDP,给每个包加上一个ID标识也能解决问题
Server:服务器端
static void Main(string[] args)
{
IPAddress ip = Dns.GetHostByName(Dns.GetHostName()).AddressList[0];
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(new IPEndPoint(ip, 1005));
listener.Listen(150);
while (true)
{
Socket socket = listener.Accept();
RemoteClient client = new RemoteClient(socket);
client.BeginRead();
}
}
public RemoteClient(Socket sock)
{
this.M_socket = sock;
Console.WriteLine("Client Connected!{0}<--{1}", sock.LocalEndPoint,sock.RemoteEndPoint);
streamToClient = new NetworkStream(sock);
//定义缓存大小
buffer = new byte[BufferSize];
}
public void BeginRead()
{
AsyncCallback callBack = new AsyncCallback(OnReadComplete);
streamToClient.BeginRead(buffer, 0, BufferSize, callBack, null);
}
private void OnReadComplete(IAsyncResult ar)
{
try
{
bytesRead = streamToClient.EndRead(ar);
string message = Encoding.Unicode.GetString(buffer, 0, bytesRead);
ParameterizedThreadStart start = new ParameterizedThreadStart(handleProtocol);
start.BeginInvoke(pro, null, null);
}
catch (Exception e)
{}
}
private void handleProtocol(object obj)
{
string pro = obj as string;
receiveFile(pro);
}
private void receiveFile(string protocol)
{
string path = @"E:/" + protocol.FileName;
byte[] fileBuffer = new byte[BufferSize];
FileInfo file = new FileInfo(path);
using (FileStream fs = file.Open(file.Exists ? FileMode.Append : FileMode.CreateNew, FileAccess.Write, FileShare.None))
{
try
{
int bytesRead = M_socket.Receive(fileBuffer);
long totalBytes = fs.Length;
M_socket.Send(BitConverter.GetBytes(totalBytes));
long length = BitConverter.ToInt64(fileBuffer, 0);
while (totalBytes < length)
{
bytesRead = streamToClient.Read(buffer, 0, BufferSize);
fs.Write(buffer, 0, bytesRead);
fs.Flush();
totalBytes += (long)bytesRead;
Console.WriteLine("Receiving {0} bytes...", totalBytes);
}
Console.WriteLine("Total {0} bytes received,Done!", totalBytes);
}
catch (Exception e)
{ }
}
} Client客户端:
static void Main(string[] args)
{
RemoteClient Rclient = new RemoteClient();
Console.ReadLine();
}
public RemoteClient()
{
try
{
ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = Dns.GetHostByName(Dns.GetHostName()).AddressList[0];
ClientSocket.Connect(ip, 1005);
}
buffer = new byte[BufferSize];
Console.WriteLine("Server Connected!{0}-->{1}", ClientSocket.LocalEndPoint, ClientSocket.RemoteEndPoint);
streamToServer = new NetworkStream(ClientSocket);
ConsoleKey key;
List<string> PathList = new List<string>();
Console.WriteLine("输入上传路径后回车,按G开始执行任务...");
do
{
Console.WriteLine("请输入上传路径...");
string filePath = Console.ReadLine();
PathList.Add(filePath);
key = Console.ReadKey(true).Key;
}while(key != ConsoleKey.G);
for(int i=0;i<PathList.Count;i++)
{
if (File.Exists(PathList[i].ToString()))
{
BeginSendFile(PathList[i].ToString());
}
else
{
Console.WriteLine("此{0}路径无效!",PathList[i].ToString());
}
}
}
public void BeginSendFile(string filePath)
{
ParameterizedThreadStart start = new ParameterizedThreadStart(SendFile);
start.BeginInvoke(filePath, null, null);
}
private void SendFile(object obj)
{
string filePath = obj as string;
SendFile(filePath);
}
public void SendFile(string filePath)
{
IPEndPoint endpoint = ClientSocket.LocalEndPoint as IPEndPoint;
int listeningPort = endpoint.Port;
string fileName = Path.GetFileName(filePath);
NetworkStream stream = new NetworkStream(ClientSocket);
// 创建文件流
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
byte[] fileBuffer = new byte[BufferSize];
Buffer.BlockCopy(BitConverter.GetBytes(fs.Length), 0, fileBuffer, 0, PerLongCount);
ClientSocket.Send(fileBuffer, 0, PerLongCount + Encoding.Default.GetBytes(fileName, 0, fileName.Length, fileBuffer, PerLongCount), SocketFlags.None);
ClientSocket.Receive(fileBuffer);
int bytesRead;
long totalBytes;
fs.Position = totalBytes = BitConverter.ToInt64(fileBuffer, 0);
try
{
do
{
Thread.Sleep(20);
bytesRead = fs.Read(fileBuffer, 0, fileBuffer.Length);
stream.Write(fileBuffer, 0, bytesRead);
totalBytes += (long)bytesRead;
} while (bytesRead > 0);
}
catch
{}
}
主要的代码都在这里了,好了,现在问题来了,在同一个客户端同时执行多个任务却有问题,不知哪位高手可帮小弟看一看,是不是同一个客户端的端口号不支持多任务的异步传输呢?
{ if (ic.g_SendNum>0)
{
for (int i = 1; i < ic.g_SendNum + 1; i++)
{
SendThread = new Thread(new ParameterizedThreadStart(SendServer));
SendThread.Start(i);
SendThreadListen = new Thread(new ParameterizedThreadStart(ic.SendLinten));
SendThreadListen.Start(ic.iniSend[i]); }
}
if (ic.g_ReceiveNum>0)
{
for (int i = 1; i < ic.g_ReceiveNum + 1; i++)
{
ReceiveThread = new Thread(new ParameterizedThreadStart(ReceiveServer));
ReceiveThread.Start(i);
ReceiveThreadListen = new Thread(new ParameterizedThreadStart(ic.ReceiveLinten));
ReceiveThreadListen.Start(ic.iniSend[i]); }
}
} public void ReceiveServer(Object objct)
{
int nIndex = (int)objct;
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, ic.iniReceive[nIndex].nRecPort);
Socket ser = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//绑定网络地址
ser.Bind(ipep);
Console.WriteLine("This is a Server,Host name is {0}", Dns.GetHostName());
//等待客户端连接
ic.Log("Waiting for a client...");
ser.Listen(0);
EndPoint ipConnect = null;
try
{
Socket newsock = ser.Accept();
ipConnect = ser.RemoteEndPoint;
ic.Log("Waited...");
Object oj = newsock as Object;
while (true)
{
ic.Log("开始接收文件 ... ");
if (!ic.ReceiveFile(ic.iniReceive[nIndex].strAimPath, newsock, ic.iniReceive[nIndex]))
{
ic.Log(ipConnect.ToString()+"异常断开,10秒后重新连接");
newsock.Close();
ser.Close();
ReceiveServer(objct);
break;
}
Console.WriteLine("接收完成 ... ");
ic.Log("接收完成 ... ");
}
}
catch (Exception e)
{
ic.Log(ipConnect.ToString() + "连接失败");
string strContent = e.Message.ToString() + Environment.NewLine + e.StackTrace.ToString();
ic.Log(strContent);
ic.Log("10秒钟后重新连接");
ser.Close();
ReceiveServer(objct);
Thread.Sleep(10 * 1000);
}
}
public void SendServer(Object oj)
{
int nIndex = (int)oj;
byte[] data = new Byte[20 * 1024];
ic.iniSend[nIndex].bDicExist = ic.CreateDirectory(ic.iniDicPath, MyDict);
Console.WriteLine("This is a Client, host name is {0}", Dns.GetHostName());
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(ic.iniSend[nIndex].strIP), ic.iniSend[nIndex].nSendPort);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ic.Log("Connecting ... ");
try
{
server.Connect(ipep);
if (server.Connected)
{
ic.Log("Connected ... ");
while (true)
{
ic.FileListDict.Clear();
ic.Log("开始遍历 ... ");
for (int i = 1; i < ic.iniSend[nIndex].sendnum + 1; i++)
{
if (Directory.Exists(ic.iniSend[nIndex].strSourcePath[i]))
{
ic.Log("开始遍历:" + ic.iniSend[nIndex].strSourcePath[i]);
if (!ic.FindFile(ic.iniSend[nIndex].strSourcePath[i], server, MyDict, i, ic.iniSend[nIndex]))
{
ic.Log(ic.iniSend[nIndex].strIP+"遍历失败,10秒后重新遍历");
server.Close();
SendServer(oj);
break;
}
ic.Log(ic.iniSend[nIndex].strSourcePath[i] + " 遍历完成 ... ");
}
else
{
ic.Log(ic.iniSend[nIndex].strSourcePath[i] + "路径不存在");
Console.WriteLine("路径不存在");
} }
ic.WriteDirectory(ic.iniDicPath, MyDict);
CP2PMessage msgEnd = new CP2PMessage();
msgEnd.nMessageTypes = (sbyte)(9);
data = Tool.StructToBytes(msgEnd);
if (data.Length > 0)
server.Send(data, data.Length, 0);
Console.WriteLine("遍历完成 ... ");
ic.Log("遍历完成 ... ");
if (ic.iniSend[nIndex].CompareFile > 120)
{
ic.iniSend[nIndex].CompareFile = 0;
for (int j = 1; j < ic.iniSend[nIndex].sendnum + 1; j++)
{
ic.FunCompareFile(ic.iniSend[nIndex].strSourcePath[j], server, j, ic.iniSend[nIndex]);
}
ic.Log("文件匹配完成... "); }
Thread.Sleep(10 * 1000);
}
}
else
{
ic.Log(ic.iniSend[nIndex].strIP + "初始化连接失败,10秒后重新连接");
server.Close();
SendServer(oj);
}
}
catch (Exception e)
{
ic.Log(ic.iniSend[nIndex].strIP + "连接失败");
string strContent = e.Message.ToString() + Environment.NewLine + e.StackTrace.ToString();
ic.Log(strContent);
ic.Log("重新连接");
SendServer(oj);
}
}