socket监听久了cpu太高

m0_37748860 2018-07-25 02:24:53
服务器端socket服务一共有3个线程
1.监听接收消息
2.接收图片
3.向客户端发送图片
cpu几十分钟就飙到90多。求大佬给个解决方案。

...全文
266 点赞 收藏 12
写回复
12 条回复
m0_37748860 2018年08月10日
引用 10 楼 wangjun8868 的回复:
看这个文件 用异步
https://www.cnblogs.com/qc-id-01/p/7520633.html

或者用第三方组件,比如HP-SOCKET ,用起来很简单!

异步解决了,tks。
回复 点赞
编程有钱人了 2018年07月27日
像传输文件这种工作,如果是业务量大,完全不建议用TCP!除非使用情况比较少,文件小等
回复 点赞
编程有钱人了 2018年07月27日
看这个文件 用异步
https://www.cnblogs.com/qc-id-01/p/7520633.html

或者用第三方组件,比如HP-SOCKET ,用起来很简单!
回复 点赞
编程有钱人了 2018年07月27日
while 写线程

client_Thread = new Thread(ReceiveData);
client_Thread.Start(connection);

不合适,因为每次收到消息都开启一个线程!切线程里面有嵌套了线程,极其不合理,
像你这杨的业务,需要用异步,不用线程!


回复 点赞
m0_37748860 2018年07月26日
//第三个,发送图片

private void SendImg()
{

while (true)
{
string path=Application.StartupPath + "\\订单\\";
DirectoryInfo TheFolder = new DirectoryInfo(path);
foreach (FileInfo NextFile in TheFolder.GetFiles())
{
string[] split_msg_order = NextFile.Name.Split('-');
string orderno=split_msg_order[1];
string[] splitMSG = split_msg_order[0].Split(',');
string ToUsername=splitMSG[3];
for (int i = 0; i < userList.Count; i++)
{
if (userList[i].username == ToUsername)
{
// 给在线的其他用户发送广播消息
// 通知有新用户加入
SendtoClient(null, userList[i], split_msg_order[0]);
IPAddress IMGIP = IPAddress.Parse(userList[i].ImgIPEndPoint.Split(':')[0]);
int port = int.Parse(userList[i].ImgIPEndPoint.Split(':')[1]);
IPEndPoint imgip = new IPEndPoint(IMGIP,port);
SendFile(imgip, NextFile.FullName);
File.Delete(NextFile.FullName);
}
}
}
Thread.Sleep(30000);
}

}
回复 点赞
m0_37748860 2018年07月26日
引用 6 楼 wangjun8868 的回复:
肯定代码有问题,贴代码给你解决!

代码写的不好将就看吧,解决问题。

void Start()
{
//第一个,收发消息
server_Thread = new Thread(ServerStart);
server_Thread.Start();

//第二个,接收图片
InitIMG();

//第三个,发送图片
threadSendIMG = new Thread(SendImg);
threadSendIMG.Start();
}


//第一个,收发消息
 private void ServerStart()
{
Socket connection = null;
// Socket socketWatch = o as Socket;
while (true)
{
try
{
//接受Andorid信息
connection = server_Socket.Accept();


}
catch (Exception ex)
{
// MessageBox.Show("start error: " + ex.Message);
return;
}
clientep = (IPEndPoint)connection.RemoteEndPoint;
string str = string.Format("connectsuccess,{0},{1}", "", clientep.Address + ":" + clientep.Port);
byte[] data = new byte[1024];
data = Encoding.UTF8.GetBytes(str);
connection.Send(data, data.Length, SocketFlags.None);

client_Thread = new Thread(ReceiveData);
client_Thread.Start(connection);
}
}
private void ReceiveData(object o)
{
Socket socketSend = o as Socket;
Byte[] buffer;
while (true)
{
string message = null;
//将接收到的信息存入到内存缓冲区,并返回其字节数组的长度
try
{
buffer = new Byte[1024];
int length = socketSend.Receive(buffer);
if (length <= 0)
{
string outname = "";
for (int i = 0; i < userList.Count; i++)
{
if (userList[i].usersocket == socketSend)
{

outname = userList[i].username;
userList.RemoveAt(i);
UpdateDGV(userList);
}
}
for (int i = 0; i < userList.Count; i++)
{
string outline = string.Format("logout,{0},{1}", outname, "");
SendtoClient(socketSend, userList[i], outline);
}
socketSend = null;
return;
}
//将机器接受到的字节数组转换为人可以读懂的字符串
message = Encoding.UTF8.GetString(buffer, 0, length);
UpdateTxt(message);

}
catch (Exception ex)
{

}

clientep = (IPEndPoint)socketSend.RemoteEndPoint;

try
{
string[] splitstring = message.Split(',');
IPEndPoint clientIPEndPoint = clientep;
switch (splitstring[0])
{
// 如果是登录信息,向客户端发送应答消息和广播有新用户登录消息
case "login":
User user = new User(splitstring[1], clientIPEndPoint, socketSend, splitstring[3]);
string userItem = user.username + "," + user.userIPEndPoint;
// 往在线的用户列表添加新成员
bool usercontain = false;
int index = 0;
foreach (var l in userList)
{
if (l.username.Equals(user.username))
{
usercontain = true;
index = userList.FindIndex(item => item.Equals(l));
}

}
if (!usercontain)
{

userList.Add(user);
// AddItemToListView(userItem);
UpdateDGV(userList);
}
else
{

}

Thread sendThread = new Thread(SendData);
sendThread.Start(socketSend);
sendThread.Join();
for (int i = 0; i < userList.Count; i++)
{
if (userList[i].username != user.username)
{
SendtoClient(socketSend, userList[i], message);
}
}


break;
case "logout":
for (int i = 0; i < userList.Count; i++)
{
if (userList[i].username == splitstring[1])
{

userList.RemoveAt(i);
UpdateDGV(userList);
}
}
for (int i = 0; i < userList.Count; i++)
{
SendtoClient(socketSend, userList[i], message);
}

break;
case "talk":
string tousername = splitstring[3];
for (int i = 0; i < userList.Count; i++)
{
if (userList[i].username == tousername)
{

SendtoClient(socketSend, userList[i], message);
}
}

break;
}
}
catch
{ }


}
}


//第二个,接收图片
  public void InitIMG()
{

serverIMGSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint SelfImgIPEndPoint = new IPEndPoint(Dns.GetHostAddresses("")[2], 8888);
serverIMGSocket.Bind(SelfImgIPEndPoint); //绑定IP地址:端口
serverIMGSocket.Listen(20); //设定最多10个排队连接请求
Console.WriteLine("启动监听{0}成功", serverIMGSocket.LocalEndPoint.ToString());
Thread myThread = new Thread(ListenIMGConnect);
myThread.Start();
}

private void ListenIMGConnect()
{
while (true)
{

try
{
Socket clientSocket = serverIMGSocket.Accept();
Thread receiveThread = new Thread(RECVIMG);
receiveThread.Start(clientSocket);
}
catch
{
break;
}

}
}
public static void RECVIMG(object clientSocket)
{
Socket client = clientSocket as Socket;
//获得客户端节点对象
IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;
//获得[文件名]
string SendFileName = System.Text.Encoding.UTF8.GetString(TransferFiles.ReceiveVarData(client));
//获得[包的大小]
string bagSize = System.Text.Encoding.UTF8.GetString(TransferFiles.ReceiveVarData(client));
//获得[包的总数量]
byte[] dd = TransferFiles.ReceiveVarData(client);
string ss = System.Text.Encoding.UTF8.GetString(dd);
int bagCount = int.Parse(ss);

//获得[最后一个包的大小]
string bagLast = System.Text.Encoding.UTF8.GetString(TransferFiles.ReceiveVarData(client));
string fullPath = Path.Combine(Application.StartupPath + "\\订单\\", SendFileName);
if (File.Exists(fullPath))
return;
//创建一个新文件
FileStream MyFileStream = new FileStream(fullPath, FileMode.Create, FileAccess.Write);
//已发送包的个数
int SendedCount = 0;
while (true)
{
byte[] data = TransferFiles.ReceiveVarData(client);
if (data.Length == 0)
{
break;
}
else
{
SendedCount++;
//将接收到的数据包写入到文件流对象
MyFileStream.Write(data, 0, data.Length);
//显示已发送包的个数

}
}
//关闭文件流
MyFileStream.Close();
//关闭套接字
client.Close();

}

放不下了,下面第三个

回复 点赞
编程有钱人了 2018年07月26日
肯定代码有问题,贴代码给你解决!
回复 点赞
以专业开发人员为伍 2018年07月25日
什么叫做“一共有3个线程”呢?


异步、事件驱动的程序,当没有消息到来时不会占用任何线程,十几万客户端跟服务器联系可能也不过有十几个、二十几个线程在瞬间工作几十毫秒,然后就结束了。哪有什么阻塞着的线程在那里?
回复 点赞
xuzuning 2018年07月25日
你都不说你是怎么写的,如何能有正确解法?
回复 点赞
m0_37748860 2018年07月25日
引用 1 楼 twotuli_software 的回复:
解决方案是重写。

重写应该是什么思路?
回复 点赞
维秀斯丢丢 2018年07月25日
解决方案是重写。
回复 点赞
cheng2005 2018年07月25日
找个真正有水平的开发人员重写你说的这些内容是最简单可靠的解决方案。
回复 点赞
发动态
发帖子
C#
创建于2007-09-28

8.4w+

社区成员

64.0w+

社区内容

.NET技术 C#
社区公告
暂无公告