Avatar billede stuffedk Nybegynder
16. marts 2009 - 20:43 Der er 12 kommentarer og
1 løsning

c++ windows socket tcp

Jeg er lige begyndt at lege med c++ og jeg har næsten lige læst en bog/lang tutorial om emnet. Jeg følte ikke det var så svært, for jeg er ret hård til PHP og det minder en del om. Der er selvfølgelig lige det med at der er forskellige variabeltyper og memory adresser og den slags.

Any way, da jeg nu var færdig med bogen gik det op for mig at jeg kun havde lært nok til at kunne lave en avanceret konsol lommeregner... Jeg prøvede at søge på google efter "c++ windows socket tcp" fordi jeg gerne ville prøve at lære at "networke", men jeg kan forstå nogle af tutorialsne godt nok til at kunne lave mit eget netværksprogram. Den første jeg prøvede: http://www.codeproject.com/KB/IP/beginningtcp_cpp.aspx

Skriver noget om "link libws2_32.a to your project in order to use the API that are necessary for TCP/IP" og allerede der faldt jeg fra, for det aner jeg ikke hvordan man gør.

Nu er jeg helt stuck. Er der ikke nogen der kan poste det NEMMEST MULIGE eksempel på en "server" og en "client". Så lidt forvirrende elementer i scriptse som overhovedet muligt tak, evt kan de bare udskrive den rå data i konsollen. Så det nærmest bliver et chat program.

Håber meget nogen kan hjælpe!
Avatar billede arne_v Ekspert
16. marts 2009 - 20:51 #1
Hvis du bruger en GCC baseret compiler command line paa windows saa angiver du bare:

gcc ... -lws2_32 ...

for at linke winsock funktionerne med ind i din kode.

Med andre compilere skal man angive det paa anden vis.

Fortael hvad du bruger, saa kan vi sikkert fortaelle dig hvordan.
Avatar billede arne_v Ekspert
16. marts 2009 - 20:57 #2
Jeg kan proeve at bixe et super simpelt client server eksempel.
Avatar billede arne_v Ekspert
16. marts 2009 - 21:34 #3
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

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

void server(int port)
{
    int sd, sd2, status, len, ix;
    char req[100];
    struct sockaddr_in local;
    sd = socket(AF_INET, SOCK_STREAM, 0);
    if(sd<0)
    {
        printf("Error creating socket: %s\n", strerror(errno));
      goto fin;
    }
    local.sin_family = AF_INET;
    local.sin_port = htons(port);
    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;
    }
    status = listen(sd, 5);
    if(status < 0)
    {
        printf("Error listening socket: %s\n", strerror(errno));
        goto fin;
    }
    sd2 = accept(sd, 0, 0);
    if(sd2 < 0)
    {
        printf("Error accepting socket: %s\n", strerror(errno));
        goto fin;
    }
    ix=0;
    memset(req, 0, sizeof(req));
    while(ix <  2 + *((short *)req))
    {
        len = recv(sd2, req + ix, sizeof(req) - ix - 1, 0);
        ix = ix + len;
    }
    req[ix] = '\0';
    printf("request = %s\n", req + 2);
    status = send(sd2, "OK", strlen("OK"), 0);
    if(status < 0)
    {
        printf("Error sending response\n");
        goto fin;
    }
fin:
    closesocket(sd2);
    closesocket(sd);
}

int main(int argc,char *argv[])
{
    WSADATA WSAData;
    WSAStartup(0x0101, &WSAData);
    server(1234);
    WSACleanup();
    return 0;
}
Avatar billede arne_v Ekspert
16. marts 2009 - 21:34 #4
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

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

void client(char *host, int port, char* msg)
{
    int sd, status, len, ix;
    short tmp;
    char resp[512];
    struct sockaddr local,remote;
    struct hostent *hostinfo;
    sd = socket(AF_INET, SOCK_STREAM, 0);
    if(sd < 0)
    {
        printf("Error creating socket: %s\n", strerror(errno));
        goto fin;
    }
    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;
    }
    hostinfo = gethostbyname(host);
    if(!hostinfo)
    {
        printf("Error looking up host: %s\n", host);
        goto fin;
    }
    remote.sa_family = hostinfo->h_addrtype;
    memcpy(remote.sa_data + 2, hostinfo->h_addr_list[0], hostinfo->h_length);
    *((short *)remote.sa_data) = htons(port);
    status = connect(sd, &remote, sizeof(remote));
    if(status != 0)
    {
        printf("Error connecting to host: %s port: %d\n", host, port);
        goto fin;
    }
    tmp = strlen(msg);
    status = send(sd, (char *)&tmp, sizeof(tmp), 0);
    if(status < 0)
    {
        printf("Error sending request\n");
        goto fin;
    }
    status = send(sd, msg, strlen(msg), 0);
    if(status < 0)
    {
        printf("Error sending request\n");
        goto fin;
    }
    ix = 0;
    while ((len = recv(sd, resp + ix, sizeof(resp) - ix - 1, 0)) > 0)
    {
        ix = ix + len;
    }
    resp[ix] = '\0';
    printf("response = %s\n", resp);
fin:
    closesocket(sd);
}

int main(int argc,char *argv[])
{
    WSADATA WSAData;
    WSAStartup(0x0101, &WSAData);
    client("localhost", 1234, "Dette er en test!");
    WSACleanup();
    return 0;
}
Avatar billede stuffedk Nybegynder
17. marts 2009 - 01:26 #5
Hej arne mange tak for dine hurtige svar og den tid du har brugt på eksemplet.

Jeg bruger Dev-C++ fra bloodshed til windows og jeg bruger bare den GUI der er og trykker F9 når jeg compiler, jeg ved ikke om der også er en command line compiler, det kigger jeg lige på. Jeg kigger også lige på de scripts du har lavet og skriver hvis jeg får problemer, men det ser umiddelbart fint ud.
Avatar billede stuffedk Nybegynder
17. marts 2009 - 01:39 #6
Hej igen.

Jeg fik linkeren til at virke og det hele virker helt fint. Mange tak. Lejer lige lidt videre med det :)
Avatar billede arne_v Ekspert
17. marts 2009 - 01:40 #7
Man skal bare ind i noget options og sætte -lws2_32.
Avatar billede arne_v Ekspert
17. marts 2009 - 01:41 #8
Den protokol jeg har valgt mellem client og server er lidt grim - den er assymetrisk da client->server bruger et længde prefix mens server->client afsluttes ved at lukke socket. Men sådan passede det lige bedst.
Avatar billede arne_v Ekspert
17. marts 2009 - 01:42 #9
Husk at socket kode ikke we Windows specifikt, hvis du bruger nogle andre header filer og ændrer closesocket til close, så compiler kode på *nix også.
Avatar billede stuffedk Nybegynder
17. marts 2009 - 02:48 #10
Hej arne det lyder godt og det fungere også godt.

Jeg er igang med at prøve at om rokere lidt rundt så jeg måske kan få lavet en slags chat program selv. Jeg har sat følgende ind inden at msg bliver sendt i clienten:

        while (msg != "quit")
    {
    cin >> msg;
    cout << msg;
    }

Jeg ved godt at den kun vil kunne komme til at sende når jeg skriver quit, men det er bare en start. Men programmet crasher efter cin. Hvordan kan det være? (jeg har includeret de headers jeg skulle). Any way, jeg laver en ny tråd når jeg får flere problemer :) for du har svaret på mit spørgesmål, så lav et svar så får du points!
Avatar billede arne_v Ekspert
17. marts 2009 - 03:01 #11
svar
Avatar billede arne_v Ekspert
17. marts 2009 - 03:01 #12
Hvordan er msg erklæret i din version af programmet ?
Avatar billede stuffedk Nybegynder
17. marts 2009 - 03:25 #13
void client(char *host, int port, char* msg)

ikke andre steder
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

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