Avatar billede cronck Nybegynder
13. maj 2005 - 23:46 Der er 42 kommentarer og
1 løsning

Netværksprogrammering i C++

Er der nogen som vil hjælpe mig med at lave et server program, og et klient program?
Klienter skal bare kunne chatte, senere skal de måske have mulighed for at sende filer til hinanden... Grunden til at jeg siger det med filer nu er så at jeg ikke risikerer at skulle skifte mellem TCP/UDP senere hen.
Jeg ved heller ikke hvad der er smartest at bruge (TCP/UDP)?
Mildt sagt aner jeg ikk hvad forskellen er, så hvis at du kan forklare det ville det også være lækkert.

Nogen som kan hjælpe med noget kode til at starte med?
Avatar billede arne_v Ekspert
13. maj 2005 - 23:51 #1
så skal du til at kigge på socket programmering

jeg har nogle eksemple rpå både client og server men de er ret primitive

jeg kan også finde nogle links
Avatar billede bertelbrander Novice
13. maj 2005 - 23:51 #2
TCP er sikker transmision af pakker, UDP er usikker levering.
UDP er let, TCP lidt mere besværligt.

Jeg lavede en gang et lille P-P chat program, det bruger UDP:
http://home20.inet.tele.dk/midgaard/sample.html#chat
Avatar billede cronck Nybegynder
13. maj 2005 - 23:52 #3
arne: hvis at de er primitive har jeg vel også nemmere ved at forstå dem :-)

bertelbrander: jeg kigger på det... P2P er vejen :D
Avatar billede arne_v Ekspert
13. maj 2005 - 23:53 #4
Avatar billede arne_v Ekspert
13. maj 2005 - 23:54 #5
et TCP server program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include <windows.h>
#include <errno.h>

struct data
{
  short int a;
  long int b;
  float c;
  double d;
  char e[5];
};

void swap(char *x,int n)
{
    int i;
    char tmp;
    for(i=0;i<n/2;i++)
    {
        tmp=x[i];
        x[i]=x[n-i-1];
        x[n-i-1]=tmp;
    }
}

int main(int argc,char *argv[])
{
  WSADATA WSAData;
  int sd,sd2,status,len,ix;
  char *p;
  struct sockaddr_in local;
  struct data msg;
  /* windows specifik */
  WSAStartup(0x0101,&WSAData);
  /* create socket */
  sd=socket(AF_INET,SOCK_STREAM,0);
  if(sd<0) {
      printf("Error creating socket: %s\n",strerror(errno));
      goto fin;
  }
  /* bind socket */
  local.sin_family=AF_INET;
  local.sin_port = htons(12345);
  local.sin_addr.s_addr = INADDR_ANY;
  status=bind(sd,(struct sockaddr *)&local,sizeof(local));
  if(status<0) {
      printf("Error binding socket: %s\n",strerror(errno));
      goto fin;
  }
  /* listen socket */
  status=listen(sd,5);
  if(status<0) {
      printf("Error listening socket: %s\n",strerror(errno));
      goto fin;
  }
  /* accept connection */
  sd2=accept(sd,0,0);
  if(sd2<0) {
      printf("Error accepting socket: %s\n",strerror(errno));
      goto fin;
  }
  /* read data */
  p=(char *)&msg;
  ix=0;
  while((len=recv(sd2,p+ix,sizeof(msg)-ix,0))>0) {
    ix=ix+len;
  }
  /* swap bytes on little endian system like x86 PC's */
  swap((char *)&msg.a,sizeof(msg.a));
  swap((char *)&msg.b,sizeof(msg.b));
  swap((char *)&msg.c,sizeof(msg.c));
  swap((char *)&msg.d,sizeof(msg.d));
  /* print data read */
  printf("%d %d %f %f %s\n",msg.a,msg.b,msg.c,msg.d,msg.e);
fin:
  /* close sockets */
  closesocket(sd2);
  closesocket(sd);
  /* windows specifik */
  WSACleanup();
  return 0;
}
Avatar billede arne_v Ekspert
13. maj 2005 - 23:55 #6
et TCP client program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include <windows.h>
#include <errno.h>

void get(char *hostname,int port,char *path)
{
  int sd,status,len,ix,tmp;
  char cmd[512],resp[51200];
  struct sockaddr local,remote;
  struct hostent *hostinfo;
  /* create socket */
  sd=socket(AF_INET,SOCK_STREAM,0);
  if(sd<0) {
      printf("Error creating socket: %s\n",strerror(errno));
      goto fin;
  }
  /* bind socket */
  local.sa_family=AF_INET;
  memset(local.sa_data,0,sizeof(local.sa_data));
  status=bind(sd,&local,sizeof(local));
  if(status<0) {
      printf("Error binding socket: %s\n",strerror(errno));
      goto fin;
  }
  /* lookup host */
  hostinfo=gethostbyname(hostname);
  if(!hostinfo) {
      printf("Error looking up host: %s\n",hostname);
      goto fin;
  }
  /* connect to host */
  remote.sa_family=hostinfo->h_addrtype;
  memcpy(remote.sa_data+2,hostinfo->h_addr_list[0],hostinfo->h_length);
  *((short *)remote.sa_data)=port;
  tmp=remote.sa_data[0];
  remote.sa_data[0]=remote.sa_data[1];
  remote.sa_data[1]=tmp;
  status=connect(sd,&remote,sizeof(remote));
  if(status!=0) {
      printf("Error connecting to host: %s port: %d\n",hostname,port);
      goto fin;
  }
  /* send GET request */
  sprintf(cmd,"GET %s HTTP/1.1\r\nHost: %s\r\n\r\n",path,hostname);
  status=send(sd,cmd,strlen(cmd),0);
  if(status<0) {
      printf("Error sending GET request\n");
      goto fin;
  }
  /* read response */
  ix=0;
  while ((len=recv(sd,resp+ix,sizeof(resp)-ix-1,0))>0) {
      ix = ix + len;
  }
  resp[ix]='\0';
  printf("%s",resp);
fin:
  closesocket(sd);
  return;
}

int main(int argc,char *argv[])
{
  WSADATA WSAData;
  WSAStartup(0x0101,&WSAData);
  get("www.eksperten.dk",80,"/");
  WSACleanup();
  return 0;
}
Avatar billede arne_v Ekspert
13. maj 2005 - 23:56 #7
og et link til noget decideret winsock:

http://tangentsoft.net/wskfaq/
Avatar billede cronck Nybegynder
13. maj 2005 - 23:57 #8
Hmm... Troede kun at Winsock var i Visual Basic?
Kan jeg også bruge det i C++? fordi at det var møg nemt i VB :-)
Avatar billede arne_v Ekspert
14. maj 2005 - 00:00 #9
winsock er nok mere til C++ end til VB

men husk - konceptet er det samme - formentligt er det ldt mere bøvlet i C++

kig evt. på koden ovenfor
Avatar billede arne_v Ekspert
14. maj 2005 - 00:02 #10
udover winsock så har du også et higher level API kaldet WinInet.

Der er et eksempel på http://www.codeproject.com/internet/w3client.asp
Avatar billede arne_v Ekspert
14. maj 2005 - 00:02 #11
jeg har derimod aldrig rodet med UDP i C++
Avatar billede cronck Nybegynder
14. maj 2005 - 00:04 #12
Omg... Du er hurtig!
Det tager lige lidt tid at kigge på tingene, vender tilbage senere ;-)
Avatar billede cronck Nybegynder
14. maj 2005 - 00:09 #13
Arne har du det samme til et Windows program med forms?
Avatar billede cronck Nybegynder
14. maj 2005 - 00:11 #14
Er der egentlig ikk nogen som har lavet en DLL som indeholder alt det der, som man bare kan kalde med ip:port og lign...?
Avatar billede arne_v Ekspert
14. maj 2005 - 00:19 #15
Jeg programmerer sjældent GUI.

Jeg har noget C++ kode som wrapper socket, hvis du er interesseret.
Avatar billede cronck Nybegynder
14. maj 2005 - 00:21 #16
wrapper?
Den tror jeg lige at jeg skal have forklaret ;-)
Avatar billede arne_v Ekspert
14. maj 2005 - 00:24 #17
---(simpelt interface)--->wrapper---(komplekst interface)--->egentlig kode
Avatar billede cronck Nybegynder
14. maj 2005 - 00:26 #18
Alt hvad der kan gøre tingene nemmere for mig er velkommen :)
Avatar billede arne_v Ekspert
14. maj 2005 - 00:30 #19
http://www.vajhoej.dk/arne/avu2/INC/IP.H
http://www.vajhoej.dk/arne/avu2/LIB/IP.C

men de bruger en del andre stumper - og de er ifdef'et til diverse platforme - jeg
tror måske at de vil forvirre mere end de vil hjælpe
Avatar billede cronck Nybegynder
14. maj 2005 - 00:32 #20
Ja, de ser ikke ligefrem overskuelige ud i mine øjne... ;)
Kan man ikk finde et komponent som at bare kan smidde ind og kalde de bestemte funktioner når at man har brug for dem?
Avatar billede cronck Nybegynder
14. maj 2005 - 00:33 #21
Den software som jeg laver behøver heller ikke at virke på andre platforme end WinXP...
Avatar billede arne_v Ekspert
14. maj 2005 - 00:34 #22
Borland C++Builder har måske noget

men generelt så er C++ programmører gør det selv folk
Avatar billede cronck Nybegynder
14. maj 2005 - 00:40 #23
C++ er måske heller ikke noget for mig da jeg mere er "jeg skal have det hele leveret på et sølv-fad" typen.... ;-)

Grunden til at jeg har valgt C++ er fordi at det sprog (efter min opfattelse) bliver eksekveret hurtigst....
Er jeg helt forkert på den der?
Avatar billede ksoren Nybegynder
14. maj 2005 - 00:53 #24
udp: hvis klienten sidder på et lukket netværk bag diverse routere/firewalls, vil du muligvis løbe ind i forskellige problemer, når serveren skal sende trafik tilbage.

Med tcp vil det køre uden problemer.
Avatar billede cronck Nybegynder
14. maj 2005 - 00:54 #25
Hvilke sprog passer til emnet og måske endda er lidt nemmere at have med at gøre, kan du anbefale?
Avatar billede cronck Nybegynder
14. maj 2005 - 01:18 #26
Har jeg nogen andre muligheder i C++ til at lave netværk med som ikke allerede er nævnt?
Avatar billede bertelbrander Novice
14. maj 2005 - 01:23 #27
Jeg synes nu ikke det er ret svært.
Der findes en del eksempler, så bare find noget du kan bruge og byg videre på det.
Avatar billede cronck Nybegynder
14. maj 2005 - 01:29 #28
Jeg har faktisk kigget på diverse eksempler siden klokken var 22:00 :-)
Det nemmeste var hvis at jeg fandt en danks tutorial som gennemgik hver enkelt del, så jeg selv bliver nød til at skrive og forstå tingene...
Avatar billede bertelbrander Novice
14. maj 2005 - 01:32 #29
Der er en række artikler på dansk om emnet her:
http://www.udvikleren.dk/articles.php?techid=1
Avatar billede cronck Nybegynder
14. maj 2005 - 01:35 #30
Jeg har prøvet med denne her: http://www.udvikleren.dk/article.php?aid=193&techid=1
Jeg tror bare at problemet er at jeg bliver forvirret med alt det der linux pjat... Og det skal jeg heller ikke bruge til noget... :)
Avatar billede cronck Nybegynder
14. maj 2005 - 01:53 #31
Jeg tror at jeg gør klogt i at læse godt og grundigt på http://tangentsoft.net/wskfaq/

Vender tilbage senere
Avatar billede cronck Nybegynder
14. maj 2005 - 04:04 #32
Jeg har fundet sådan en ting som at jeg snakkede om tidligere, et komponent...
http://www.dart.com/dotnet/sockets.asp

Problemet med det her er at det udløber, og koster penge... :(
Avatar billede arne_v Ekspert
14. maj 2005 - 11:06 #33
Det er jo .NET

.NET library kommer med et socket bibliotek som er langt nemere at bruge end
i normal C/C++ socket/winsock
Avatar billede arne_v Ekspert
14. maj 2005 - 11:08 #34
C++ er ikke automatisk hurtigere end andre sprog, men netop fordi du har
muligheden for at kontrollere meget selv, så er der ofte nogle optimerings
muligheder, men man kan ikke både blæse og have mel i munden
Avatar billede cronck Nybegynder
14. maj 2005 - 13:53 #35
"man kan ikke både blæse og have mel i munden" - Hehe... nice udtryk :)

Ja, jeg bruger .NET... Er det eksempel du har skrevet da ikke i .NET?
Avatar billede arne_v Ekspert
14. maj 2005 - 14:00 #36
nej - de bruger almindelig winsock

de kan bygges med C++.NET som unmanaged applikationer

men ved at skifte til en managed .NET applikation kan du bruge .NET
API'et som er noget simplere

Det relevante namespace er

System.Net.Sockets
Avatar billede cronck Nybegynder
14. maj 2005 - 15:04 #37
Lyder jo som det jeg har brug for... :)

Har du et eksempel?
Avatar billede arne_v Ekspert
14. maj 2005 - 15:07 #38
ikke i C++ (jeg laver kun .NET kode i C# og VB.NET aldrig i C++.NET, J# eller JScript.NET)

men docs har masser af eksempler
Avatar billede cronck Nybegynder
14. maj 2005 - 15:17 #39
Det kunne være at jeg skulle lave skidtet i VB.NET så...

Jeg fandt det her komponent igår: http://www.codeproject.com/useritems/UnoLibsNet_V2.asp

Nu skal jeg bare finde ud af at bruge det...
Ellers, hvordan mener du at jeg gør det nemmest?
Avatar billede cronck Nybegynder
14. maj 2005 - 15:59 #40
Arne hvis at du lige smidder et svar, kan jeg oprette spm. i en passende kategori :-)
Avatar billede arne_v Ekspert
14. maj 2005 - 16:01 #41
jeg tror nok at jeg ville bruge System.Net.Sockets fremfor det lib
Avatar billede arne_v Ekspert
14. maj 2005 - 16:01 #42
svar
Avatar billede cronck Nybegynder
14. maj 2005 - 17:04 #43
Jeg vil selv lave et lib fra bunden... Tror jeg gør det både nemmere og smartere... :-)

Det nye spm: http://www.eksperten.dk/spm/617797
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
Kurser inden for grundlæggende programmering

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