我寫了一個服務端可以連接多個客戶端,現在的問題是當多個客戶端連接之后,每個客戶端第一次通訊沒問題但是第二次通訊的話只有第一個連接上的才能成功通訊,還有就是當我關閉服務器的按鈕之后,并不能關閉連接,只能斷開其中一個或者兩個,還請各位大神指教指教!!
這是監聽連接代碼片段
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;
}
}
}
這是運行界面

uj5u.com熱心網友回復:
沒人回復嗎
uj5u.com熱心網友回復:
找個socket異步通信示例代碼消化一下吧。監聽、Accept、Receive應該都用多執行緒異步處理,不同socket干不同事。代碼好像沒放全,不仔細看了,8成是一個socket干了多個活導致的阻塞。uj5u.com熱心網友回復:
沒太明白你的意思。貼出的代碼不全,只有服務端的代碼,沒有客戶端的代碼,服務端的代碼也不全。能否先將你的需求說明白,然后再分析代碼。uj5u.com熱心網友回復:
需求就是,一個服務端可以連接n個客戶端,然后需要實作的是某一個已經連接的客戶端發資訊給服務端之后,服務端再群發給每一個連接的客戶端。現在我測驗用的是TCP&DUP測驗工具所以就沒有客戶端代碼
就是當連接了多個客戶端之后就會出現 第一個連接的客戶端可以一直通訊 其他的就只能進行一次通訊,當其他不能通訊的時候 服務端可以接收到第一個連接的客戶端的資訊 但是發不出去
uj5u.com熱心網友回復:
你的需求是要求 TCP 雙向通信,即服務端、客戶端的角色在隨時變化,這種場景使用一個 TCP 會話來做,必須使用異步方式,因為你需要處理發送、接收的并行操作。同步模式下,接收是阻塞的,在接收等待時無法進行發送操作。如果網路規模小(所有設備在同一網段),可考慮使用 UDP 的組播,但是結果不可靠。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/262731.html
標籤:C#
