SocketClient i wątek

Odpowiedz Nowy wątek
2015-05-14 20:38
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();
            }
        }

    }

Pozostało 580 znaków

2015-05-14 20:49
0

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

Pozostało 580 znaków

2015-05-14 20:58
0

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

Pozostało 580 znaków

2015-05-14 21:49
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();
                        }
            }
        }

    }
edytowany 2x, ostatnio: krisrk4, 2015-05-14 21:51

Pozostało 580 znaków

2015-05-14 21:51
0

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

Pozostało 580 znaków

2015-05-14 21:53
0

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

Pozostało 580 znaków

2015-05-14 21:55
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

Chcesz pomocy - pokaż kod - abrakadabra źle działa z techniką.

Pozostało 580 znaków

2015-05-14 22:03
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?

Pozostało 580 znaków

2015-05-14 22:07
0

async.

Pozostało 580 znaków

2015-05-15 15:29
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?

Pozostało 580 znaków

2015-05-15 15:39
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");
}
jako iż to będzie z osobnego wątku to w wtfEventHandler powinno być Invoke :) - abrakadaber 2015-05-15 15:43

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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