C# Socket通讯问题

weixin_47256859 2021-02-23 09:15:59
我写了一个服务端可以连接多个客户端,现在的问题是当多个客户端连接之后,每个客户端第一次通讯没问题但是第二次通讯的话只有第一个连接上的才能成功通讯,还有就是当我关闭服务器的按钮之后,并不能关闭连接,只能断开其中一个或者两个,还请各位大神指教指教!!
这是监听连接代码片段
 private void Startsocket()
{

try
{
IPAddress ip = IPAddress.Any;
//当开始监听时候,在服务器创建一个负责IP地址跟端口号的Socket
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint point = new IPEndPoint(ip, 9090);
//监听
socketWatch.Bind(point);
//连接数量为10个
socketWatch.Listen(10);

}
catch { throw; }
}

这是客户端连接处理片段
public void ListenClickConnect(object o)
{
Socket socketWatch = o as Socket;
//等待用户连接创建一个负责通信的Socket
while (true)
{
//最大连接数
int number = 10;
if (disSocket.Count > number)
{
socketWatch.Close();
socketWatch.Dispose();
ShowMsg("连接数量已达到上限");
}
try
{
//关闭服务器时 跳出循环
if (stop)
{
break;
}
//等到客户端新的连接
socketSend = socketWatch.Accept();
//将远程客户端IP地址存储到泛型集合中
disSocket.Add(socketSend.RemoteEndPoint.ToString(), socketSend);
Thread th = new Thread(Receive);
th.IsBackground = true;
th.Start(socketSend);
ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + "连接成功");
//timer.Start();
AddKJ();

}
catch { break; }
}

这是关闭服务器代码片段
bool stop = false;
private void Stop_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i <= namenumber; i++)
{
Image images = gridcontrol.FindName("image" + i) as Image;
Label label = gridcontrol.FindName("label" + i) as Label;
if (images != null)
{
gridcontrol.Children.Remove(images);
gridcontrol.UnregisterName("image" + i);
gridcontrol.Children.Remove(label);
gridcontrol.UnregisterName("label" + i);
}
Image image = gridcontrol.FindName("image") as Image;
image.Visibility = Visibility.Visible;
}
ShowMsg("关闭服务");
if (startandstop == false)
{
startandstop = true;
startbut.IsEnabled = true;
stopbut.IsEnabled = false;
startbut.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF5B93E4"));
stopbut.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFF7CDCD"));
}
//断开通讯和关闭监听
if (socketSend != null && socketSend.Connected)
{
socketSend.Shutdown(SocketShutdown.Both);
socketSend.Close();
socketSend.Dispose();
stop = true;
socketWatch.Close();
socketWatch.Dispose();
disSocket.Clear();
}
else
{
stop = true;
socketWatch.Close();
socketWatch.Dispose();
}

}

接收客户端发来的信息片段

int erro = 0;

private void Receive(object o)
{
socketSend = o as Socket;
while (true)
{
try
{
//客户端连接成功后服务器接收发来消息
byte[] buffer = new byte[1024 * 1024 * 2];
//实际接收有效字节数
int r = socketSend.Receive(buffer);
if (r == 0)
{
erro += 1;
Erroe(erro);
break;
}
string str = Encoding.UTF8.GetString(buffer, 0, r);
ShowMsg(str);
SendData(str);

}
catch
{
break;
}
}
}

这是运行界面






...全文
439 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
glb21 2021-02-28
  • 打赏
  • 举报
回复
直接用mqtt协议做就行
  • 打赏
  • 举报
回复

private void Receive(object o)
        {
            socketSend = o as Socket;//socketSend这个变量在哪定义的,是不是被覆盖了
            while (true)
            {
                try
                {
                    //客户端连接成功后服务器接收发来消息
                    byte[] buffer = new byte[1024 * 1024 * 2];
                    //实际接收有效字节数
                    int r = socketSend.Receive(buffer);
                    if (r == 0)
                    {
                        erro += 1;
                        Erroe(erro);
                        break;
                    }
                    string str = Encoding.UTF8.GetString(buffer, 0, r);
                    ShowMsg(str);
                    SendData(str);
 
                }
                catch
                {
                    break;
                }
            }
        }
另外,看你描述,客户端连上后要反复发消息,还需要考虑很多事情,粘包、心跳等等
weixin_47256859 2021-02-24
  • 打赏
  • 举报
回复
用异步解决了 加了心跳包 谢谢大佬们 感谢
datafansbj 2021-02-23
  • 打赏
  • 举报
回复
你的需求是要求 TCP 双向通信,即服务端、客户端的角色在随时变化,这种场景使用一个 TCP 会话来做,必须使用异步方式,因为你需要处理发送、接收的并行操作。同步模式下,接收是阻塞的,在接收等待时无法进行发送操作。

如果网络规模小(所有设备在同一网段),可考虑使用 UDP 的组播,但是结果不可靠。
weixin_47256859 2021-02-23
  • 打赏
  • 举报
回复
引用 3 楼 datafansbj 的回复:
没太明白你的意思。贴出的代码不全,只有服务端的代码,没有客户端的代码,服务端的代码也不全。能否先将你的需求说明白,然后再分析代码。
需求就是,一个服务端可以连接n个客户端,然后需要实现的是某一个已经连接的客户端发信息给服务端之后,服务端再群发给每一个连接的客户端。现在我测试用的是TCP&DUP测试工具所以就没有客户端代码就是当连接了多个客户端之后就会出现 第一个连接的客户端可以一直通讯 其他的就只能进行一次通讯,当其他不能通讯的时候 服务端可以接收到第一个连接的客户端的信息 但是发不出去
datafansbj 2021-02-23
  • 打赏
  • 举报
回复
没太明白你的意思。贴出的代码不全,只有服务端的代码,没有客户端的代码,服务端的代码也不全。能否先将你的需求说明白,然后再分析代码。
X-i-n 2021-02-23
  • 打赏
  • 举报
回复
找个socket异步通信示例代码消化一下吧。监听、Accept、Receive应该都用多线程异步处理,不同socket干不同事。代码好像没放全,不仔细看了,8成是一个socket干了多个活导致的阻塞。
weixin_47256859 2021-02-23
  • 打赏
  • 举报
回复
没人回复吗

110,477

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧