23. april 2007 - 11:26Der er
64 kommentarer og 1 løsning
Kan jeg erstatte min lykke?
Hej jeg har arbejdet med en chat server og har et problem nemlig at den køre som en uendelig lykke. Er der ikke en måde jeg kan lave om på dette da det ikke er fedt at alle clients og servern bruger 100% cpu.
Her kan i se koden lavet af Micheal H som jeg har tænkt mig at lave fejlen på.
using System.IO; using System.Net; using System; using System.Threading; using N = System.Net; // Genvej - så man ikke skal skrive så meget. using System.Collections;
class TalkServ { // TcpListener lytter efter connections hele tiden og man kan snakke med den via TcpClient eller Socket System.Net.Sockets.TcpListener server; // Hashtable høre til system.collections og er en beholder for objector. public static Hashtable handles; public static Hashtable handleByConnect;
public static void Main() { TalkServ TS = new TalkServ(); }
public TalkServ() { // Fortæller Hashtable hvor mange Objector den må indeholde?! ikke sikker handles = new Hashtable(100); handleByConnect = new Hashtable(100); // Server lytter på port 4296 kunne være mange andre men det er bare random. // Ved ikke at skrive IP men bare port lytter den på alle interfaces som maskinen har i sig. server = new System.Net.Sockets.TcpListener(4296); Console.WriteLine("Starter server"); while (true) { server.Start(); if (server.Pending()) { // tager imod en client N.Sockets.TcpClient connection = server.AcceptTcpClient(); Console.WriteLine("Connection Oprettet"); // Tager i mod bruger og sender ham til BackForth som der fra hjælper ham igennem opsætningen. BackForth BF = new BackForth(connection); } } }
public static void SendToAll(string name, string msg) { // Laver en slags multicast, alt som kommer fra en client bliver sendt til alle som er connectet til Min server StreamWriter SW; ArrayList ToRemove = new ArrayList(0); N.Sockets.TcpClient[] tc = new N.Sockets.TcpClient[TalkServ.handles.Count]; TalkServ.handles.Values.CopyTo(tc, 0); for (int i = 0; i < tc.Length; i++) { try { if (msg.Trim() == "" || tc[i] == null) continue; SW = new StreamWriter(tc[i].GetStream()); // Standard for hvordan den skal vise den intastet verdi. SW.WriteLine(name + ": " + msg); // Reset så den er klar til ny intastning. SW.Flush(); SW = null; } catch (Exception e44) { // Vis der sker en fejl i connection vil den skrive det i servern og smide clienten ud fra programmet. e44 = e44; string g = (string)TalkServ.handleByConnect[tc[i]]; TalkServ.SendSysMsg("** " + g + " ** Connection Lukket."); TalkServ.handles.Remove(g); TalkServ.handleByConnect.Remove(tc[i]); } } }
public static void SendSysMsg(string msg) { StreamWriter SW; ArrayList ToRemove = new ArrayList(0); N.Sockets.TcpClient[] tc = new N.Sockets.TcpClient[TalkServ.handles.Count]; TalkServ.handles.Values.CopyTo(tc, 0); for (int i = 0; i < tc.Length; i++) { try { if (msg.Trim() == "" || tc[i] == null) continue; SW = new StreamWriter(tc[i].GetStream()); SW.WriteLine(msg); SW.Flush(); SW = null; } catch (Exception e44) { e44 = e44; TalkServ.handles.Remove(TalkServ.handleByConnect[tc[i]]); TalkServ.handleByConnect.Remove(tc[i]); } } } }//end of class TalkServ
public BackForth(System.Net.Sockets.TcpClient c) { client = c; Thread t = new Thread(new ThreadStart(init)); t.Start(); }
private string GetHandle() { //Skriv navn SW.WriteLine("Skriv dit navn? "); SW.Flush(); return SR.ReadLine(); }
private void run() { try { string l = ""; while (true) { l = SR.ReadLine(); TalkServ.SendToAll(handle, l); } } // skriver i consol hvad problemet er med connection til client. catch (Exception e44) { Console.WriteLine(e44); } }
private void init() { SR = new System.IO.StreamReader(client.GetStream()); SW = new System.IO.StreamWriter(client.GetStream()); SW.WriteLine("Velkommen til MinChatServer"); handle = GetHandle(); while (TalkServ.handles.Contains(handle)) { SW.WriteLine("Dette navn er desvære ibrug!"); handle = GetHandle(); } TalkServ.handles.Add(handle, client); TalkServ.handleByConnect.Add(client, handle); TalkServ.SendSysMsg("** " + handle + " ** Er kommet ind i chatten."); SW.WriteLine("Du kan nu skrive...\r\n-------------------------------"); SW.Flush(); Thread t = new Thread(new ThreadStart(run)); t.Start(); } }
using System.IO; using System.Net; using System; using System.Threading; using N = System.Net; // igen forkortelse af system.net using System.Collections; using System.Windows.Forms; using System.ComponentModel; using System.Runtime.InteropServices;
class TalkUser {
static Form talk; static N.Sockets.TcpClient TC; // forkortelse af System.Net.Sockets.TcpClient
men tilbage til mit problem :) hvad gør jeg med lykken?
Synes godt om
Slettet bruger
23. april 2007 - 13:42#14
Jamen ffs
public static void Main() ER en console default contructer, det kan godt være du HAR en windows form i din client, men det bliver ÅBNEt via din console Din klasse ser i øvrigt sådan her ud:
class TalkUser {
Var din client et windows form projekt havde din klasse set nogenlunde sådan ud:
public partial class Form1 : Form {
Ergo er din client som grundplan et console projekt hvor du bruger forms = giver ingen mening.
Grunden til jeg siger det er, at du ikke behøver den lykke hvis din klient kører som Windows form project
Ok. Nu er jeg ikke ekspert på dette område det jeg siger er at jeg køre den i en windows application for der virker kode. I consol application kan jeg ikke få den til at virke men somsagt er jeg helder ikke nogle expert inde for dette område jeg er stadig igang med at lære c# samt VS. :D
Jeg har med høj sansynlighed lavet noget forkert og det søger jeg hjælp til. Det giver ingen mening men det virker. Jeg vil gerne lave det på din måde men det er ikke bare noget jeg lige kan gøre.
Synes godt om
Slettet bruger
23. april 2007 - 15:03#16
Altså at køre serveren i console er nok det rigtige valg, da du ikke skal gøre så meget ved den, den skal bare køre og virke.
En client skal du somregel bruge et grafisk interface til, så der vil man typisk bruge windows forms. Du kan sagtens lave en fungerende client i forms.
Prøv engang. Lav et nyt windows form projekt og smid din kode derind. Husk at alt der skal køre hele tiden i en lykke f.eks skal køre i sin egen tråd, ellers låser det formen. Dvs ting som en nytte tråd, der lytter på beskeder fra serveren.
Ok jeg har set hvad jeg kunne gøre jeg er somsagt ikke serlig god men er intraseret i at lave dette.
Jeg har nu lavet en rigtig windows form men der er nogle ting jeg bare ikke kan og er ikke helt sikker på det er rigtig vil i ikke være sød at tage et kig.
Jeg har 2fejl i form1.cs The name 'TC' does not exist in the current context The name 'TC' does not exist in the current context
Jeg har 1fejl i form1.designer.cs No overload for 'form1_load' matches delegate 'System.EventHandler'
Form1.cs ------------------------ using System; using System.IO; using System.Threading; using N = System.Net; // igen forkortelse af system.net using System.Collections.Generic; using System.ComponentModel; using System.Runtime.InteropServices; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms;
namespace MinChatClient2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); N.Sockets.TcpClient TC; // forkortelse af System.Net.Sockets.TcpClient TC = new N.Sockets.TcpClient(); TC.Connect("192.168.160.118", 4296); Thread t = new Thread(new ThreadStart(run)); t.Start(); }
public void Event() { while (true) { Application.DoEvents(); } }
Application.DoEvents() skal væk fra din form1.cs, så fjern Event() funktionen.
Lav det noget i denne stil (lavet i hånden så der er nok fejl)
using System; using System.IO; using System.Threading; using N = System.Net; // igen forkortelse af system.net using System.Collections.Generic; using System.ComponentModel; using System.Runtime.InteropServices; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms;
namespace MinChatClient2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); N.Sockets.TcpClient TC; // forkortelse af System.Net.Sockets.TcpClient TC = new N.Sockets.TcpClient(); TC.Connect("192.168.160.118", 4296); Thread t = new Thread(new ThreadStart(run)); t.Start(); }
public void Event() { while (true) { Application.DoEvents(); } }
har rattet fejlene men den får min server til at gå ned
using System; using System.IO; using System.Threading; using N = System.Net; // igen forkortelse af system.net using System.Collections.Generic; using System.ComponentModel; using System.Runtime.InteropServices; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms;
namespace MinChatClient2 { public partial class Form1 : Form { N.Sockets.TcpClient TC; // forkortelse af System.Net.Sockets.TcpClient public Form1() { InitializeComponent();
TC = new N.Sockets.TcpClient(); TC.Connect("192.168.160.118", 4296); Thread t = new Thread(new ThreadStart(run)); t.Start(); }
public void Event() { while (true) { Application.DoEvents(); } }
Her er det du har skrevet men rattet så ingen fejl meddegelser men. den åbner ikke og servern crasher!
using System; using System.IO; using System.Threading; using N = System.Net; // igen forkortelse af system.net using System.Collections.Generic; using System.ComponentModel; using System.Runtime.InteropServices; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms;
namespace MinChatClient2 { public partial class Form1 : Form { N.Sockets.TcpClient TC; // forkortelse af System.Net.Sockets.TcpClient public Form1() { InitializeComponent(); TC = new N.Sockets.TcpClient(); TC.Connect("192.168.160.118", 4296); Thread t = new Thread(new ThreadStart(run)); t.Start(); }
public void Event() { while (true) { Application.DoEvents(); } }
Du kan sende til serveren, og serveren pinger clienten hvert sekund for at se om du er "i live". Du kan tilslutte så mange clienter som du har lyst til på samme tid
vil den ikke sige der kun er 1 client for (int i = 0; i < ClientList.Count; i++) da den null stiller den når en client connector?!
Synes godt om
Slettet bruger
24. april 2007 - 11:13#37
I ListenForConnections funktionen tilføjer den en client til det array hver gang en client connecter, og fjerner en når de disconnecter fra IsAlive. Så det array indeholder altid alle aktive clients
Synes godt om
Slettet bruger
24. april 2007 - 11:16#38
Den SKAL sende den ping commando, ellers opdager den ikke at klienten er disconnected. Du kan gøre det på klient siden at du siger
Kan du give et hint til server delen hvor den skal sende beskeden til alle andre og en selv. så man kan se hvad man selv har skrevet..
Server jeg snakker om nu
Synes godt om
Slettet bruger
24. april 2007 - 12:53#46
Du kan bare tilføje det du skriver til de andre til listen når du sender
lav en lykke, der siger for hver client i ClientList, send en kommando med argument, hvor argument er det han har skrevet, og hvis clienten i listen er = den der har sendt beskeden, så ignorer.
if (CurrentClient.Available > 0) { // Læser data fra clients StreamReader reader = new StreamReader(CurrentClient.GetStream()); // Container for data string Data = reader.ReadLine(); SendToUsers(CurrentClient, Data); }
Error 1 An object reference is required for the nonstatic field, method, or property 'ChatServer.Program.SendToUsers(System.Net.Sockets.TcpClient, string)' C:\Documents and Settings\Nick Larsen\Desktop\TCP Chat\ChatServer\ChatServer\Program.cs 96 29 ChatServer
yes jeg tager noget lættere så. Vis du laver en svar besked så får du nogle velfortjænte points
Synes godt om
Slettet bruger
24. april 2007 - 14:38#65
svar :)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.