עבור לתוכן

שאלה בנוגע לצ'אט סרבר בC#

Featured Replies

פורסם

בניתי סרבר וקליינט בC# הסרבר בCONSOLE הקליינט בWINFORM עכשיו אני רוצה להעביר את הסרבר שיהיה WINFORM גם.

בקיצור בניתי את החלון עוד לא סיימתי את כל הדברים כמובן בגלל שנתקלתי בבעיה.

הבעיה היא שכאשר אני מגיע לשורה

Socket socket = listener.AcceptSocket();

החלון נתקע משום מה, כאשר הסרבר בקונסול הכל עובד מצוין ואני לא מצליח להבין מה אני לא עושה נכון, אם תוכלו לעזור לי אני אשמח.

הנה הקוד של הרסבר (אני חייב לציין שאני רק לומד לתכנת ואני עושה הרוב לבד אז כל עזרה תהיה מבורכת, תודה מראש)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CommunicatorLibrary;
using System.Net.Sockets;
using System.Collections;
using System.Threading;

namespace WinFormServer
{
public partial class frmServer : Form
{
static TcpListener listener = new TcpListener(9358);
static ArrayList clients = new ArrayList();
static bool keepRunning = true;


public frmServer()
{
InitializeComponent();
}

private void btnColor_Click(object sender, EventArgs e)
{
// Show the color dialog.
DialogResult result = colorDialog1.ShowDialog();
}

static void Listen2Clients()
{
while (keepRunning)
{
Socket socket = listener.AcceptSocket();
Comm myComm = new Comm();
myComm.GotData += new SocketHandler(myComm_GotData);
myComm.StopListening += new CommunicationEndedHandler(myComm_StopListening);
myComm.Connect(socket);
clients.Add(myComm);
}
}


static void myComm_StopListening(object sender, EventArgs e)
{
clients.Remove(sender);
}


static void myComm_GotData(object sender, SocketEventArgs e)
{
foreach (Comm item in clients)
{
try
{
item.Send(e.Data);
}
catch
{
clients.Remove(sender);
}
}
}

private void loginToolStripMenuItem_Click(object sender, EventArgs e)
{
listener.Start();
Thread t = new Thread(new ThreadStart(Listen2Clients));
t.IsBackground = true;
t.Start();
Listen2Clients();
}

פורסם

AcceptSocket היא פונקציה חוסמת (blocking). זה אומר שכל עוד היא לא הסתיימה, הת'רד שמריץ אותה תקוע (במקרה הספציפי הזה, היא תסתיים רק כשלקוח כלשהו יתחבר לשרת). הבעיה היא שהת'רד שמריץ אותה הוא הת'רד שאחראי על ה-GUI, ולכן הוא לא מגיב.

הפתרון לזה הוא להריץ את כל הטיפול בסוקט בת'רד נפרד.

הסיבה שבקונסול זה עובד מצוין היא שאין לך דרך לראות שהת'רד שלו תקוע.

פורסם
  • מחבר

קודם כל תודה רבה על התגובה המהירה, משיטוט מהיר באינטרנט ראיתי שאני צריך אולי לעשות לו INVOKE, אני לא כל כך זוכר איך עושים את זה אני בדיוקמנסה לרענן את זיכרוני.

העיניין הוא שחשבתי שפתחתי THREAD חדש בקטע קוד הנ"ל

private void loginToolStripMenuItem_Click(object sender, EventArgs e)
{
listener.Start();
Thread t = new Thread(new ThreadStart(Listen2Clients));
t.IsBackground = true;
t.Start();
Listen2Clients();
}

אם זו לא הדרך אולי תוכל לכוון אותי?

פורסם

פעלת נכון, חוץ מהשורה האחרונה, שמיותרת. הקריאה ל-t.Start כבר תדאג לקרוא לפונקציה Listen2Clients.

פורסם
  • מחבר

מיליון תודות, כנראה שקראתי לפונקציה פעמיים ואז זה נתקע, ברגע שעשיתי מה שאמרת והורדתי את השורה האחרונה הכל עוד מעולה "מוריד את הכובע".

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים