Valutazione 4.87/ 5 (100.00%) 5838 voti

Condividi:        

PROGRAMMARE IN C# USANDO VISUAL STUDIO

Problemi di HTML? Di PHP, ASP, .NET, JSP, Perl, SQL, JavaScript, Visual Basic..?
Vuoi realizzare programmi in C, C++, Java, Ruby o Smalltalk, e non sai da che parte cominciare?
Entra qui e troverai le risposte!

Moderatori: Triumph Of Steel, archimede

PROGRAMMARE IN C# USANDO VISUAL STUDIO

Postdi LuxSkyWalker » 23/03/07 18:35

Ciao a tutti!!!
Sono un giovane programmatore, laureando in informatica...sto realizzando con Visual Studio un protocollo appllicativo di comunicazione tra un pc e un palmare, usando come linguaggio il C# (.NET)...sono abbastanza a buon punto, ma attualmente sono bloccato con i socket di tcp...c'è qualcuno che se ne intende e può aiutarmi?Oppure, c'è qualcuno che conosce un buon forum dove posso trovare aiuto?
Grazie a tutti...
CiAo CiAo
LuxSkyWalker!
LuxSkyWalker
Utente Junior
 
Post: 18
Iscritto il: 14/12/06 19:56

Sponsor
 

Postdi hydra » 24/03/07 14:28

Se qualcuno qui ti sa dare una mano sicuramente te la darà, io non sono in grado. Se vuoi un buon forum per .NET, a mio parere il migliore è dotnethell.it. ;)
Avatar utente
hydra
Moderatore
 
Post: 7002
Iscritto il: 19/07/04 08:06
Località: Vallis Duplavis

Postdi LuxSkyWalker » 24/03/07 16:03

Lo spero...ma in ogni caso grazie per l'attenzione...
CiAo CiAo
LuxSkyWalker!
LuxSkyWalker
Utente Junior
 
Post: 18
Iscritto il: 14/12/06 19:56

Postdi zello » 26/03/07 11:19

Io ho pistolato un po' con i sockets in c#, tempo fa. Se mi ricordo bene non è che ci fossero grosse differenze rispetto ai socket bsd classici,
però se mi dici che problemi hai forse posso darti una mano.
Il faut être toujours ivre. Tout est là : c'est l'unique question. Pour ne pas sentir l'horrible fardeau du Temps qui brise vos épaules et vous penche vers la terre,il faut vous enivrer sans trêve...
Avatar utente
zello
Moderatore
 
Post: 2351
Iscritto il: 06/05/02 13:44

Postdi tekanet » 26/03/07 13:32

Anche UGIdotNET, l'user group italiano è ben fornito come forum e frequentato da ottimi programmatori e MVP MS. Consigliato.

tK
tekanet
Utente Senior
 
Post: 173
Iscritto il: 03/09/02 10:22
Località: Milano sud-ovest

Postdi LuxSkyWalker » 26/03/07 16:49

Dunque...nel protocollo applicativo che sto implementando utilizzo un socket che gestisce la connessione tra pc e palmare, facendo partire la connessione da quest'ultimo...dopo essersi connessi, continuano a fare ping-pong finchè l'utente non decide di terminare la connessione chiudendo il socket.
Ora sto sviluppando la parte che invia stringhe e file dal pc al palmare...ma non riesco a capire se posso utilizzare il socket già esistente o se devo usarne un altro nuovo...sia utilizzando la stessa porta client,sia utilizzandone un'altra, mi va in eccezione dicendomi che il client(palmare) rifiuta la connessione...spero di essere stato abbastanza chiaro...
Se qualcuno ha qualche dritta, èil benvenuto...grazie!!!
CiAo CiAo
LuxSkyWalker!
LuxSkyWalker
Utente Junior
 
Post: 18
Iscritto il: 14/12/06 19:56

Postdi zello » 26/03/07 17:30

Indipendentemente dal linguaggio di programmazione e dalla piattaforma, tanto i sockets sono i sockets ovunque, con poche differenze, la tua situazione è:
- su pc hai uno socket in stato listening su una porta (prendiamo la 12345 per esempio)
- dal palmare ti connetti (sempre usando un socket) a detta porta (di solito in questi casi il bind è su di una porta a caso, prendiamo la 54321)
- questo crea un socket in stato connected tra la 54321/tcp del palmare e la 12345/tcp del pc; in più, la porta 12345/tcp del pc rimane in stato listening.
Il problema è che ora devi gestire il fatto che sul pc hai sia un socket che è pronto a ricevere ulteriori connessioni, sia un socket che è già connesso e pronto ad inviare e ricevere dati. Tradizionalmente in questi casi o si lancia un nuovo thread che si occupa del socket connesso, mentre il vecchio thread rimette la porta in stato di listening e aspetta ulteriori connessioni, oppure si fa del multiplexing utilizzando select (che tra l'altro su .net funziona maluccio, se mi ricordo bene). Con .net c'è qualche possibilità in più in termini di chiamate asincrone, ci avevo giocato un po', il codice ce l'ho a casa.
In pratica - e in pseudo codice c++:
Codice: Seleziona tutto

//questo è il corpo di ogni thread che gestisce una connessione.
int threadMain(void* args)
{
   //args in realtà è un Socket*, vedi sotto
   Socket* sock=reinterpret_cast<Socket*>(args);

   char hi[]="Hi\n";
   sock->send(hi,strlen(hi));
   sock->recv(hi,3); //questa è bloccante.
   //chiudo il socket (suppongo sia fatto nel distruttore)
   delete sock;
   return 0;
}
int main()
{
   //ok, creo un socket tcp
   Socket s=new Socket(SOCK_STREAM);
   //lo lego alla porta 12345
   s.bind(12345);
   //accetto connessioni all'infinito, e per ciascuna avvio un thread distinto
   while(true)
   {
       Socket connected=s.listen();
       if(connected==INVALID_SOCKET)
          break;
       /*
       la riga sotto è pseudo codice per avviare un thread, il primo
       argomento è la funzione da eseguire nel contesto del nuovo thread
       (il thread entry point), la seconda è un puntatore a void che in realtà
       è l'argomento da passare al thread
       Nota: in c++ non posso passare direttamente connected, in quanto
       viene distrutto alla riga successiva perché esce di scope: sono
       costretto a passarne una copia con un lifetime diverso. Il problema
       non esisterebbe in C# o in java.
       */
       createThread(threadMain,(void*)new Socket(connected));
   }
   return 0;
}

Il faut être toujours ivre. Tout est là : c'est l'unique question. Pour ne pas sentir l'horrible fardeau du Temps qui brise vos épaules et vous penche vers la terre,il faut vous enivrer sans trêve...
Avatar utente
zello
Moderatore
 
Post: 2351
Iscritto il: 06/05/02 13:44

Postdi LuxSkyWalker » 26/03/07 18:03

Ti ringrazio per la dritta!!!
Io sto programmando in c#/.NET, ma proverò ad adattare la tua soluzine...grazie ancora!
CiAo CiAo
LuxSkyWalker!
LuxSkyWalker
Utente Junior
 
Post: 18
Iscritto il: 14/12/06 19:56

Postdi zello » 01/04/07 14:53

Toh, avevo un po' di tempo. Queste sono tre soluzioni per un echo server (un server che non fa nient'altro che rimandarti indietro ciò che gli invii).
1) usa i sockets, con un thread diverso per ogni connessione
2) stessa logica, ma usa TcpListener/TcpClient
3) usa un thread solo, il multiplexing e Socket.Select
Non ho testato un granché, ovviamente. Per provarla, connettiti a localhost porta 12345 usando telnet (ho bindato i sockets su 127.0.0.1 per motivi di sicurezza, è ovviamente facile da modificare).
Ciao.
Codice: Seleziona tutto
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;



namespace SocketTest
{
    /*
     * Helper - mutexed output
     */
    class SerializedOutput
    {
        static private System.Threading.Mutex mutex = new System.Threading.Mutex();
        static public void WriteLine(string msg)
        {
            mutex.WaitOne();
            System.Console.Out.WriteLine(msg);
            mutex.ReleaseMutex();
        }
    };
    /*
     * Standard socket
     */
    class SocketTest1
    {
        private void accept(Object o)
        {
            Socket client = (Socket)o;
            int thisconn = System.Threading.Interlocked.Increment(ref conns);
            SerializedOutput.WriteLine("Got connection #" + thisconn);
            using (client)
            {
                byte[] buf = new byte[256];
                try
                {
                    while (true)
                    {
                        int rec = client.Receive(buf);
                        if (rec == 0)
                            break;
                        client.Send(buf, rec, SocketFlags.None);
                    }
                }
                catch (Exception)
                {
                }
            }
            SerializedOutput.WriteLine("Connection " + thisconn + " closing");
        }
        static private int conns = 0;
        public void start()
        {
            SerializedOutput.WriteLine("Starting");
            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            s.Bind(new IPEndPoint(IPAddress.Loopback, 12345));
            s.Listen(50);
            using (s)
            {
                try
                {
                    while (true)
                    {
                        Socket client = s.Accept();
                        System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(accept), client);
                    }
                }
                catch (Exception ex)
                {
                    SerializedOutput.WriteLine(ex.Message);
                }
            }

        }
    }
    /*
     * using TcpClient/Listener
     */
    class SocketTest2
    {
        static private int conns=0;
        private void accept(Object o)
        {
            int thisconn = System.Threading.Interlocked.Increment(ref conns);
            SerializedOutput.WriteLine("Got connection #" + thisconn);
            TcpClient client = (TcpClient)o;
            using (client)
            {
                NetworkStream stream = client.GetStream();
                byte[] buf = new byte[256];
                try
                {
                    while (true)
                    {
                        int size = stream.Read(buf, 0, 256);
                        if (size == 0)
                            break;
                        stream.Write(buf, 0, size);
                    }
                }
                catch (Exception)
                {
                }
            }
            SerializedOutput.WriteLine("Connection " + thisconn + " closing");
        }
        public void start()
        {
            SerializedOutput.WriteLine("Starting");
            TcpListener s = new TcpListener(IPAddress.Loopback, 12345);
            s.Start();
            try
            {
                while (true)
                {
                    TcpClient client = s.AcceptTcpClient();
                    System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(accept), client);
                }
            }
            catch (Exception ex)
            {
                SerializedOutput.WriteLine(ex.Message);
            }
        }
    }
    /*
     * using Select and multiplexing
     */
    class SocketTest3
    {
        public void start()
        {
            List<Socket> lstConnections=new List<Socket>();
            List<Socket> lstReadable=new List<Socket>();
            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            server.Bind(new IPEndPoint(IPAddress.Loopback, 12345));
            server.Listen(50);
            try
            {
                while (true)
                {
                    lstReadable.Clear();
                    do
                    {
                        lstReadable.Add(server);
                        lstReadable.AddRange(lstConnections);
                        Socket.Select(lstReadable, null, null, -1);
                    } while (lstReadable.Count == 0);
                    if (lstReadable[0] == server)
                    {
                        SerializedOutput.WriteLine("New connection");
                        lstConnections.Add(server.Accept());
                    }
                    else
                    {
                        Socket s = lstReadable[0];
                        byte[] buf = new byte[256];
                        int size = s.Receive(buf);
                        if (size == 0)
                        {
                            lstConnections.Remove(s);
                            SerializedOutput.WriteLine("Connection closed");
                        }
                        else
                            s.Send(buf, size, SocketFlags.None);
                    }
                }
            }
            catch(Exception)
            {
            }
            foreach(Socket s in lstConnections)
            {
                s.Close();
            }
            server.Close();
        }

    }
    class Program
    {
        static void Main(string[] args)
        {
            //new SocketTest1().start();
            //new SocketTest2().start();
            new SocketTest3().start();
        }
    }
}

Il faut être toujours ivre. Tout est là : c'est l'unique question. Pour ne pas sentir l'horrible fardeau du Temps qui brise vos épaules et vous penche vers la terre,il faut vous enivrer sans trêve...
Avatar utente
zello
Moderatore
 
Post: 2351
Iscritto il: 06/05/02 13:44


Torna a Programmazione


Topic correlati a "PROGRAMMARE IN C# USANDO VISUAL STUDIO":


Chi c’è in linea

Visitano il forum: Nessuno e 5 ospiti