更新 'TRI_TCP_Server/TRI_TCP_Server/Run.cs'

master
ZGGSONG 3 years ago
parent 935c759181
commit 203389d97c

@ -12,24 +12,6 @@ namespace TRI_TCP_Server
{ {
public class Run public class Run
{ {
//绑定本地IP
private static string Ip = "172.17.208.203";
//绑定端口
private static string Port = "5001";
public static void Main(string[] args)
{
try
{
BeginListening(Ip, Port);
}
catch (Exception ex)
{
Console.WriteLine("监听服务器出错: " + ex.Message.ToString());
}
Console.ReadKey();
}
private static Dictionary<string, Socket> dict = new Dictionary<string, Socket>(); private static Dictionary<string, Socket> dict = new Dictionary<string, Socket>();
private static Thread threadWatch = null; private static Thread threadWatch = null;
@ -37,17 +19,16 @@ namespace TRI_TCP_Server
/// <summary> /// <summary>
/// 开始监听 /// 开始监听
/// </summary> /// </summary>
/// <param name="localIp"></param> public static void Main()
/// <param name="localPort"></param> {
public static void BeginListening(string localIp, string localPort) try
{ {
//创建服务端负责监听的套接字参数使用IPV4协议使用流式连接使用Tcp协议传输数据 //创建服务端负责监听的套接字参数使用IPV4协议使用流式连接使用Tcp协议传输数据
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//获取Ip地址对象 //获取Ip地址对象
IPAddress address = IPAddress.Parse(localIp); IPAddress address = IPAddress.Parse("0.0.0.0");
//创建包含Ip和port的网络节点对象 //创建包含Ip和port的网络节点对象
IPEndPoint endpoint = new IPEndPoint(address, int.Parse(localPort)); IPEndPoint endpoint = new IPEndPoint(address, int.Parse("5001"));
//将负责监听的套接字绑定到唯一的Ip和端口上 //将负责监听的套接字绑定到唯一的Ip和端口上
socketWatch.Bind(endpoint); socketWatch.Bind(endpoint);
//设置监听队列的长度 //设置监听队列的长度
@ -58,6 +39,12 @@ namespace TRI_TCP_Server
threadWatch.Start();//开始线程 threadWatch.Start();//开始线程
//ShowMgs("服务器启动监听成功"); //ShowMgs("服务器启动监听成功");
Console.WriteLine("服务器启动监听成功"); Console.WriteLine("服务器启动监听成功");
Console.ReadKey();
}
catch (Exception ex)
{
Console.WriteLine($"监听异常:{ex.Message}");
}
} }
/// <summary> /// <summary>
@ -71,11 +58,11 @@ namespace TRI_TCP_Server
Socket connection = socketWatch.Accept(); Socket connection = socketWatch.Accept();
if (connection.Connected) if (connection.Connected)
{ {
//将与客户端通信的套接字对象connection添加到键值对集合中并以客户端Ip做为健 //将与客户端通信的套接字对象connection添加到键值对集合中并以客户端Ip做为健,唯一标志符号
dict.Add(connection.RemoteEndPoint.ToString(), connection); dict.Add(connection.RemoteEndPoint.ToString(), connection);
//创建通信线程 //创建通信线程
ParameterizedThreadStart pts = new ParameterizedThreadStart(RecMsg); ParameterizedThreadStart pts = new ParameterizedThreadStart(RecvMsg);
Thread thradRecMsg = new Thread(pts); Thread thradRecMsg = new Thread(pts);
thradRecMsg.IsBackground = true; thradRecMsg.IsBackground = true;
thradRecMsg.Start(connection); thradRecMsg.Start(connection);
@ -91,99 +78,57 @@ namespace TRI_TCP_Server
private static void test(object socketPara) private static void test(object socketPara)
{ {
Socket socket = socketPara as Socket; Socket socket = socketPara as Socket;
while (true) string sendDir = @"D:\ServerDir";
string[] recv = GetFileSystemEntries(sendDir, null, -1, false);
foreach (var item in recv)
{ {
Console.WriteLine("请输入回车"); Net.TCPSend(socket, item, 512, 1);
Console.ReadLine(); Console.WriteLine($"{socket.RemoteEndPoint} {item} 发送成功");
Net.TCPSend(socket, @"D:\KSATProjects\2021-10-ASM\settings\SPI\Lanto_HTTP.INI", 512, 1); Thread.Sleep(500);
Console.WriteLine("发送成功");
} }
} }
/// <summary> /// <summary>
/// 接收消息 /// 接收心跳和文件
/// </summary> /// </summary>
/// <param name="socketClientPara"></param> /// <param name="socketClientPara"></param>
private static void RecMsg(object socketClientPara) private static void RecvMsg(object socketClientPara)
{ {
Socket socketClient = socketClientPara as Socket; Socket socketClient = socketClientPara as Socket;
while (true) while (true && socketClient.Connected)
{
//定义一个接受用的缓存区100M字节数组
//byte[] arrMsgRec = new byte[1024 * 1024 * 100];
//将接收到的数据存入arrMsgRec数组,并返回真正接受到的数据的长度
if (socketClient.Connected)
{ {
try try
{ {
//因为终端每次发送文件的最大缓冲区是512字节所以每次接收也是定义为512字节
byte[] _buf = new byte[25];
byte[] buffer = new byte[512];
int size = 0;
long len = 0;
string fileSavePath = @"D:\ServerDir";//获得用户保存文件的路径 string fileSavePath = @"D:\ServerDir";//获得用户保存文件的路径
if (!Directory.Exists(fileSavePath)) string[] recv = Net.RecvData(socketClient, new byte[25]);
{ switch (recv[0].TrimEnd('\0'))
Directory.CreateDirectory(fileSavePath);
}
//有文件发送才创建新文件
if (socketClient.Receive(_buf, 0, 25, SocketFlags.None) > 0)
{ {
//string recv = Encoding.Default.GetString(_buf); case "1000":
//Console.WriteLine(socketClient.RemoteEndPoint + " 接收消息: " + DateTime.Now.ToString("yyyy:MM:dd HH:mm:ss:fff")); string fileName = fileSavePath + "\\" + recv[2] + "\\" + recv[4].TrimEnd('\0');
string res = Encoding.Default.GetString(_buf); string filePath = fileSavePath + "\\" + recv[2];//检查目录是否存在
string[] str = Regex.Split(res, "(&)"); if (!Directory.Exists(filePath))
if (str[0] == "1000")
{
string fileName = fileSavePath + "\\" + str[2] + "\\" + str[4].TrimEnd('\0');
//创建文件流,然后让文件流来根据路径创建一个文件
FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write);
//从终端不停的接受数据然后写入文件里面只到接受到的数据为0为止则中断连接
DateTime oTimeBegin = DateTime.Now;
while ((size = socketClient.Receive(buffer, 0, buffer.Length, SocketFlags.None)) > 0)
{
string flag = Encoding.Default.GetString(buffer, size - 1, 1);
if (flag.Equals("`"))
{
fs.Write(buffer, 0, size - 1);
len += size;
break;
}
else
{ {
fs.Write(buffer, 0, size); Directory.CreateDirectory(filePath);
len += size;
}
}
DateTime oTimeEnd = DateTime.Now;
TimeSpan oTime = oTimeEnd.Subtract(oTimeBegin);
fs.Flush();
fs.Close();
len -= 1;
Console.WriteLine("文件保存成功:" + fileName);
string store = (len / 1024.0) > 1.0 ? (len / 1024.0) + "kb" : len + "字节";
Console.WriteLine("接收文件用时:" + oTime.ToString() + ",文件大小:" + store);
//Console.WriteLine(socketClient.RemoteEndPoint + "断开连接");
//dict.Remove(socketClient.RemoteEndPoint.ToString());
//socketClient.Close();
}
else if (str[0].TrimEnd('\0') == "1001")
{
Net.SendData(socketClient, Encoding.Default.GetBytes("1001"), 1);
} }
string recv2 = Net.RecvFile(socketClient, new byte[512], fileName);
Console.WriteLine($"{socketClient.RemoteEndPoint} {recv2}");
break;
case "1001":
Console.WriteLine($"{socketClient.RemoteEndPoint} 心跳回复");
Net.SendData(socketClient, Encoding.Default.GetBytes("1001"), 1);//服务端接收心跳后回复
break;
default:
break;
} }
} }
catch catch
{ {
Console.WriteLine(socketClient.RemoteEndPoint + "下线了"); Console.WriteLine($"{socketClient.RemoteEndPoint} 下线了");
dict.Remove(socketClient.RemoteEndPoint.ToString()); dict.Remove(socketClient.RemoteEndPoint.ToString());
break; break;
} }
} }
} }
}
/// <summary> /// <summary>
/// 关闭连接 /// 关闭连接
@ -195,5 +140,54 @@ namespace TRI_TCP_Server
socketWatch.Close(); socketWatch.Close();
Console.WriteLine("服务器关闭监听"); Console.WriteLine("服务器关闭监听");
} }
#region 获取指定目录下的所有文件
/// <summary>
/// 获取指定目录中的匹配项(文件或目录)
/// </summary>
/// <param name="dir">要搜索的目录</param>
/// <param name="regexPattern">项名模式正则。null表示忽略模式匹配返回所有项</param>
/// <param name="depth">递归深度。负数表示不限0表示仅顶级</param>
/// <param name="throwEx">是否抛异常</param>
/// <returns></returns>
public static string[] GetFileSystemEntries(string dir, string regexPattern = null, int depth = 0, bool throwEx = false)
{
List<string> lst = new List<string>();
try
{
foreach (string item in Directory.GetFileSystemEntries(dir))
{
try
{
if (regexPattern == null || Regex.IsMatch(Path.GetFileName(item), regexPattern, RegexOptions.IgnoreCase | RegexOptions.Multiline))
{
if (!IsDir(item))
{
lst.Add(item);
}
}
//递归
if (depth != 0 && (File.GetAttributes(item) & FileAttributes.Directory) == FileAttributes.Directory)
{ lst.AddRange(GetFileSystemEntries(item, regexPattern, depth - 1, throwEx)); }
}
catch { if (throwEx) { throw; } }
}
}
catch { if (throwEx) { throw; } }
return lst.ToArray();
}
/// <summary>
/// 判断目标是文件夹还是目录(目录包括磁盘)
/// </summary>
/// <param name="filepath">路径</param>
/// <returns>返回true为一个文件夹返回false为一个文件</returns>
public static bool IsDir(string filepath)
{
FileInfo fi = new FileInfo(filepath);
return (fi.Attributes & FileAttributes.Directory) != 0 ? true : false;
}
#endregion
} }
} }
Loading…
Cancel
Save