Avatar billede Slettet bruger
07. maj 2006 - 22:39 Der er 19 kommentarer og
1 løsning

Søger råd ang TCP overførsel

Jeg har lavet en Server (den der connecter) og en client (den der så acceptere connect), server er lavet i c++ og client i C#

Alt dette virker 100%, men jeg vil gerne kunne sende filer mellem de to, samtidigt med jeg kan sende diverse kommandoer.. De skal altså fungere så de kan sende og modtage filer samt udfører kommandoer på samme tid, er jeg så nød til at lave flere connections eller kan man gøre noget smart?

Først og fremmest vil jeg gerne kunne sende en fil fra min client til server (Socket baseret)

Håber nogen kan komme med en ide eller løsning..
Avatar billede arne_v Ekspert
08. maj 2006 - 00:31 #1
det var nok nemmest at have en connection til kommandoer og en eller flere til fil overførsel

det er faktisk det man gør i FTP protokollen

ellers skal du lave en protkol hvor du kan sende flere logiske streams
over en enkelt socket
Avatar billede Slettet bruger
08. maj 2006 - 01:18 #2
hmm det med logiske streams lyder indviklet
Avatar billede arne_v Ekspert
08. maj 2006 - 03:30 #3
du laver en protokol med f.eks.

2 byte : id logisk stream
2 byte : længde på data
X byte : data
Avatar billede Slettet bruger
11. maj 2006 - 18:27 #4
Dav igen.. kunne jeg bede om lidt eksempel eller ide opslag? det med bytes er ikke lige min stærke side må jeg indrømme :)

tak
Avatar billede arne_v Ekspert
11. maj 2006 - 18:53 #5
har du besluttet dig for "multiplexing" loesningen ?

jeg kan masske godt bixe noget

men foerst senere
Avatar billede Slettet bruger
11. maj 2006 - 19:08 #6
tror ikke det med flere forbindelser vil virke for mit projekt, det med logiske streams lyder meget fornuftigt :)

okay, jeg siger mange tak!
Avatar billede Slettet bruger
12. maj 2006 - 20:28 #7
ville du kigge på det arne?:)
Avatar billede arne_v Ekspert
12. maj 2006 - 20:39 #8
jeg fik ikke kigget paa det igaar

men jeg har ikke opgivet
Avatar billede Slettet bruger
12. maj 2006 - 20:47 #9
bare i orden :)

kom til at tænke på nogetda jeg så i koden:

Jeg har en accept tråd der står og acceptere alt der kommer ind, derefter opretter den en recv tråd for hver der connecter, er problemet så ikke lidt løst?..
Avatar billede arne_v Ekspert
13. maj 2006 - 02:01 #10
jo

det var jo det vi startede med: flere connections
Avatar billede arne_v Ekspert
13. maj 2006 - 04:00 #11
public class MultiplexingSocket
    {
        private Socket sock;
        private Hashtable data;
        private void Process()
        {
            byte[] tmp = new byte[4];
            int ix;
            ix = 0;
            while((ix += sock.Receive(tmp, ix, tmp.Length - ix, SocketFlags.None)) < 4);
            int id = BitConverter.ToInt32(tmp, 0);
            ix = 0;
            while((ix += sock.Receive(tmp, ix, tmp.Length - ix, SocketFlags.None)) < 4);
            int len = BitConverter.ToInt32(tmp, 0);
            byte[] buf = new byte[len];
            ix = 0;
            while((ix += sock.Receive(buf, ix, buf.Length - ix, SocketFlags.None)) < len);
            if(data[id] == null)
            {
                data[id] = buf;
            }
            else
            {
                byte[] oldbuf = (byte[])data[id];
                byte[] combibuf = new byte[oldbuf.Length + buf.Length];
                Buffer.BlockCopy(oldbuf, 0, combibuf, 0, oldbuf.Length);
                Buffer.BlockCopy(buf, 0, combibuf, oldbuf.Length, buf.Length);
                data[id] = combibuf;
            }
        }
        public MultiplexingSocket(Socket sock)
        {
            this.sock = sock;
            data = new Hashtable();
        }
        public void Send(int id, byte[] b)
        {
            sock.Send(BitConverter.GetBytes(id));
            sock.Send(BitConverter.GetBytes(b.Length));
            sock.Send(b);
        }
        public int Receive(int id, byte[] b)
        {
            while(data[id] == null)
            {
                Process();
            }
            byte[] buf = (byte[])data[id];
            if(buf.Length <= b.Length)
            {
                Buffer.BlockCopy(buf, 0, b, 0, buf.Length);
                data.Remove(id);
                return buf.Length;
            }
            else
            {
                Buffer.BlockCopy(buf, 0, b, 0, b.Length);
                byte[] newbuf = new byte[buf.Length - b.Length];
                Buffer.BlockCopy(buf, b.Length, newbuf, 0, buf.Length - b.Length);
                data[id] = newbuf;
                return b.Length;
            }
        }
    }
Avatar billede arne_v Ekspert
13. maj 2006 - 04:01 #12
demo client:

        public static void Main(string[] args)
        {
            Socket original = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            original.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 50000));
            MultiplexingSocket modified = new MultiplexingSocket(original);
            modified.Send(1, new byte[] { 1 });
            modified.Send(2, new byte[] { 2 });
            modified.Send(3, new byte[] { 3 });
            modified.Send(1, new byte[] { 1, 1 });
            modified.Send(2, new byte[] { 2, 2 });
            modified.Send(3, new byte[] { 3, 3 });
            modified.Send(1, new byte[] { 1, 1, 1 });
            modified.Send(2, new byte[] { 2, 2, 2 });
            modified.Send(3, new byte[] { 3, 3, 3 });
            original.Close();
        }
Avatar billede arne_v Ekspert
13. maj 2006 - 04:01 #13
demo server:

    public class MainClass
    {
        private static void Process(MultiplexingSocket modified, int id)
        {
            byte[] b = new byte[6];
            int total = 0;
            while(total < b.Length)
            {
                int n = modified.Receive(id, b);
                Console.Write(n + ":");
                for(int i = 0; i < n; i++)
                {
                    Console.Write(" " + b[i]);
                }
                Console.WriteLine();
                total += n;
            }
        }
        public static void Main(string[] args)
        {
            Socket original = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            original.Bind(new IPEndPoint(IPAddress.Any, 50000));
            original.Listen(1);
            MultiplexingSocket modified = new MultiplexingSocket(original.Accept());
            Process(modified, 1);
            Process(modified, 2);
            Process(modified, 3);
            original.Close();
        }
    }
Avatar billede Slettet bruger
13. maj 2006 - 12:00 #14
Det ser meget lovende ud, tak!.. altså, så jeg skal have det til at køre sm lytte tråd for hver server, og så kan ID fortælle om det er download, upload eller kommandoer der kommr ind ikke?.. men jeg jeg få både få down og upload til at virke på den måde?.. hvordan fortæller jeg om filen er færdig med at overfører fx? :)
Avatar billede Slettet bruger
13. maj 2006 - 12:35 #15
det var dog noget være sludder jeg skriver, håber du kan forstå :D
Avatar billede arne_v Ekspert
13. maj 2006 - 21:56 #16
langt det nemmeste vil være at bruge flere connections

men ja du kan bruge dette her til at mixe flere ting som f.eks. kommandoer og
overførsler i en stream

upload og download er i forvejen separeret men du kan seperare kommandoer og upload
den ene vej og status og download den anden vej med denne her teknik
Avatar billede Slettet bruger
15. maj 2006 - 08:26 #17
med flere connections mener du vel også hver sin port?
Avatar billede arne_v Ekspert
15. maj 2006 - 13:05 #18
nej

du kan godt lave flere connections til samme TcpListener (den kan accepte en
TcpClient for hver connection)
Avatar billede arne_v Ekspert
19. juni 2006 - 00:19 #19
all set ?
Avatar billede Slettet bruger
19. juni 2006 - 23:43 #20
done :)
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester