SocketClient i wątek

0

Witam mam taki problem chciałem napisać klienta który będzie na serwer wysyłał pewne dane a jak nie ma połączenia będzie pokazywał - próba 1,2,3.
Próbowałem użyć while ale tak jak w konsoli chodziło tak przy forms się zawieszało, stwierdziłem trudno spróbuję to zrobić przez timer i nowy wątek niestety nie działa pokazuje w forms tylko Server uruchomiony - dla ułatwienia podaje cały kod może ktoś pomoże, please już drugi dzień nad tym siedzę.

 
public partial class Form1 : Form
    {
        IPEndPoint koniec;
        Socket gniazdo;
        System.Timers.Timer timer_count;
        int amount_client = 0;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //int amount_client = 0;
            //TcpListener server_1 = new TcpListener(IPAddress.Parse("192.168.2.112"), 3301);
            //server_1.Start();
            koniec = new IPEndPoint(IPAddress.Parse("podaje_ip"), 3301);
            gniazdo = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            gniazdo.Bind(koniec);
            textBox1.Text = "Server uruchomiony";

            gniazdo.Listen(100);
            
            timer_count = new System.Timers.Timer();
            timer_count.Interval = 100;
            timer_count.Elapsed += timer_count_Elapsed;
            timer_count.Start();
        }

        void timer_count_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            Thread thread_new = new Thread(new ThreadStart(tray_connect));
            thread_new.Start();
        }

        void tray_connect()
        {
            try
            {
                Socket client_socket = gniazdo.Accept();
                amount_client++;
                if(client_socket.Connected)
                {
                    timer_count.Stop();
                    textBox1.Text = "Zgłosił się klient " + amount_client.ToString() + " o IP " + ((IPEndPoint)client_socket.RemoteEndPoint).Address.ToString();
                    byte[] clientdata = new byte[1024 * 2000];
                    int amountbyte = client_socket.Receive(clientdata);
                    textBox1.Text = "Odbieram plik...";
                    String data_client = Encoding.ASCII.GetString(clientdata);
                    data_client = data_client.Remove(amountbyte, data_client.Length - amountbyte);
                    textBox1.Text = data_client.ToString();
                }
                client_socket.Close();
                this.Refresh();
            }
            catch (SocketException)
            {
                this.Refresh();
                textBox1.Text = "Próba podłączenia " + amount_client;
                Application.DoEvents();
            }
            catch (IOException)
            {
                textBox1.Text = "Przerwano pobieranie pliku";
                timer_count.Start();
            }
        }


    }
0

Graficzna forma to ostatnia rzecz, jaka miałaby łączyć sie z jakimś gniazdem. Rozdziel zadania, przeorganizuj kod i wróć z czymś konkretnym.

0

Może coś więcej, jak przeorganizować kod? Utworzyć nową klasę i wywołać ją tylko w form?

0

Przebudowałem kod i dalej nic, może ktoś jednak POMOŻEEEE

Tutaj jak wygląda Forms

 

public partial class Form1 : Form
    {
        private System.Timers.Timer timer_count;
        private Server tmp_serv;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            tmp_serv = new Server(this, "192.168.42.163", 3301);
            
            timer_count = new System.Timers.Timer();
            timer_count.Interval = 1000;
            timer_count.Elapsed += timer_count_Elapsed;
            timer_count.Start();
            
        }

        private void timer_count_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            Socket client_socket = tmp_serv.tray_connect();
        }

    }

A tutaj odwołanie do Servera

 
public class Server
    {
        public XML_send_project.Form1 serv_form;
        private IPEndPoint koniec;
        private Socket gniazdo;
        private int amount_client = 0;

        public Server(Form1 serv_form, string ip_serv, int port)
        {
            this.serv_form = serv_form;
            koniec = new IPEndPoint(IPAddress.Parse(ip_serv), port);
            gniazdo = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            gniazdo.Bind(koniec);
            serv_form.textBox1.Text = "Server uruchomiony";
           
        }

        public Socket tray_connect()
        {
            while (true)
            {
                        try
                        {
                            amount_client++;
                            Socket client_socket = gniazdo.Accept();
                    
                            return client_socket;
                        }
                        catch (SocketException)
                        {

                            serv_form.textBox1.Text = "Próba podłączenia " + amount_client;
                            Application.DoEvents();
                        }
            }
        }

    }

0

Blokujesz główny wątek. Czego się spodziewasz?

0

A może jakaś praktyczna podpowiedź, jakiś kod żebym wiedział co mam zrobić, bo już za długo się z tym męczę...

0
  1. poczytaj podstawy, w szczególności o wątkach, Invoke i InvokeRequired
  2. wydziel kod serwera i klienta do osobnych klas, napisz je sensowniej
  3. nie używaj Application.DoEvents();
  4. z klas nie odwołuj się do formy tylko dodaj do klienta i serwera zdarzenie typu Info i do niego się podpinaj z formy
0

Ad.2 to jest tylko kod servera, ale ma informować że połączenie z clientem zaistniało a następnie odbierać od niego dane. Coś źle w tym zrobiłem?

0

async.

0
abrakadaber napisał(a):
  1. poczytaj podstawy, w szczególności o wątkach, Invoke i InvokeRequired
  2. wydziel kod serwera i klienta do osobnych klas, napisz je sensowniej
  3. nie używaj Application.DoEvents();
  4. z klas nie odwołuj się do formy tylko dodaj do klienta i serwera zdarzenie typu Info i do niego się podpinaj z formy

Ad.4 z klas nie odwołuj się do formy tylko dodaj do klienta i serwera zdarzenie typu Info i do niego się podpinaj z formy
Możesz powiedzieć coś więcej bo nie mogę zbytnio znaleźć dobrego wytłumaczenia w google, może jakiś przykład?

0

Taki szybki szkic:

public class Server
{
	public event EventHandler<ServerEventArgs> WtfHappened;
	
	//...
	
	public Task DoSmthStupid()
	{	
		//...
		if(smth)
		   FireWtfEvent();
	}
	
	private void FireWtfEvent()
	{
		if(WtfHappened!=null)
			WtfHappened(this, new ServerEventArgs());
	}
}

Form1:

WtfHappened += wtfEventHandler;

private void wtfEventHandler(object sender, ServerEventArgs args)
{
	MessageBos.Show("Wtf happened");
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1