Avatar billede morw Nybegynder
29. marts 2003 - 19:46 Der er 16 kommentarer og
1 løsning

Sockets: send() forkert type

Jeg ville lave den om så den sender min string, men jeg får denne fejl:

> g++ -Wall server.c -o ww
server.c: In function `int main()':
server.c:63: cannot convert `besked' from type `string' to type `const void *'

Hvad er const void *?

Hvad skal jeg gøre?

// strings
std::string besked;
besked = "morten";

send(fd2,besked,besked.size(),0); /* send to the client welcome message */
  // send(fd2,"Welcome to my server.\n",22,0); /* send to the client welcome message */
Avatar billede morw Nybegynder
29. marts 2003 - 19:48 #1
Fra sysdoc:
send(int s, const void *msg, size_t len, int flags);
Avatar billede soreno Praktikant
29. marts 2003 - 19:49 #2
Prøv at få den sendt afsted som et char array:
send(fd2, besked.c_str(), sizeof(besked.c_str()), 0);
Avatar billede morw Nybegynder
29. marts 2003 - 20:06 #3
Den sender kun mort. Hvordan kan det være?
Avatar billede arne_v Ekspert
29. marts 2003 - 20:13 #4
Fordi sizeof(besked.c_str()) returnerer sizeof af en pointer.

Brug strlen(besked.c_str()) !
Avatar billede morw Nybegynder
29. marts 2003 - 20:16 #5
Tak
Avatar billede arne_v Ekspert
29. marts 2003 - 20:17 #6
Eller besked.length() !
Avatar billede morw Nybegynder
29. marts 2003 - 20:18 #7
besked.length() vs besked.size() - hvad er forskellen?
Avatar billede arne_v Ekspert
29. marts 2003 - 20:23 #8
He he.

Jeg tror faktisk at det er besked.size() og ikke besked.length() du skal bruge.
Avatar billede arne_v Ekspert
29. marts 2003 - 20:37 #9
size returnerer den længde som allerede er gemt i objektet.

length går ud og søger efter længden.

og de vil normalt (altid ?) returnere det samme så ingen grund til
ikke at bruge size.
Avatar billede morw Nybegynder
29. marts 2003 - 20:39 #10
Tak - har du en online API du slår sådan noget op i? Et link måske?
Avatar billede arne_v Ekspert
29. marts 2003 - 20:41 #11
Hævder min STL bog ihvertfald.

Jeg har også en string header fil på et system med:
  size_type size () const  { return length(); }

:-)
Avatar billede phrame Nybegynder
29. marts 2003 - 20:41 #12
Lige til det som du har gang i kan jeg forslå følgende http://www.ecst.csuchico.edu/~beej/guide/net/bgnet.pdf ... Da jeg brugte dn tog det mig ingen tid at få styr på sockets.
Avatar billede arne_v Ekspert
29. marts 2003 - 20:42 #13
Desværre - kun en bog.
Avatar billede morw Nybegynder
29. marts 2003 - 20:46 #14
Tak - kender den godt. Har lige rodet med hans selectserver. Den er blot skrevet i ansi C, mens jeg jo prøver at få lidt C++ ind i.
Avatar billede arne_v Ekspert
29. marts 2003 - 20:46 #15
Det jeg kan finde på nettet et:
  http://www.msoe.edu/eecs/ce/courseinfo/stl/string.htm
Avatar billede phrame Nybegynder
29. marts 2003 - 20:56 #16
Jeg skrev så godt som jeg kunne det meste af beej om til c++ da jeg lavede min første client server... du kan få koden her:

#### CLIENT.CC ####
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <iostream>

#define PORT 10500 // the port client will be connecting to
#define MAXDATASIZE 100 // max number of bytes we can get at once

int main(int argc, char *argv[])
{
    int sockfd;
        struct hostent *he;
        struct sockaddr_in their_addr; // connector's address information

        if (argc != 2)
    {
            fprintf(stderr,"usage: client hostname\n");
            exit(1);
        }

        if ((he=gethostbyname(argv[1])) == NULL)
    {  // get the host info
            perror("gethostbyname");
            exit(1);
        }

        if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
            perror("socket");
            exit(1);
        }

        their_addr.sin_family = AF_INET;    // host byte order
        their_addr.sin_port = htons(PORT);  // short, network byte order
        their_addr.sin_addr = *((struct in_addr *)he->h_addr);
        memset(&(their_addr.sin_zero), '\0', 8);  // zero the rest of the struct

        if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1)
    {
            perror("connect");
            exit(1);
        }

    // SEND REQUEST
    char *message = "request";
    cout <<"Besked: " <<message <<endl <<"Længden: " <<strlen( message ) <<endl;

    if( send( sockfd, message, strlen( message )+1, 0) == -1 )
        cout <<"Fejl ved afsending af beskeden: " <<message <<endl;

    // MODTAG EMAIL ADRESSE
    int    size = 1000,
        recvLen = 0,
        done = 0,
        numBytes,
        i;
    char *buf = (char *)malloc( size );

    while( !done && ( (numBytes = recv( sockfd, buf+recvLen, size-recvLen, 0)) >= 0) )
    {
        recvLen += numBytes;

        for( i=(recvLen-numBytes); i<recvLen; i++ )
            if( buf[ i ] == '\0' )
                done = 1;

        if( (size-recvLen)<100 )
        {
            size += 1000;
            buf = (char*)realloc( buf, size );
        }
    }
    cout <<"Følgende er blevet modtaget: " <<buf <<endl;

        close(sockfd);

        return 0;
}



#### SERVER.CC #####
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <iostream.h>
using namespace std;


// Egen klasse
#include "include/g4.h"

#define MYPORT 10500
#define BACKLOG 10

int main(void)
{    string test = "test";
    const char *test2 = stoc( test );
    cout <<"T: " <<test2 <<endl;

    int sockfd, new_fd;  // listen on sock_fd, new connection on new_fd
    struct sockaddr_in my_addr;    // my address information
    struct sockaddr_in their_addr; // connector's address information

    socklen_t sin_size;

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
            perror("socket");
            exit(1);
    }

    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(MYPORT);    // short, network byte order
    my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
    memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct

    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
    {
            perror("bind");
            exit(1);
    }

    if (listen(sockfd, BACKLOG) == -1)
    {
            perror("listen");
            exit(1);
    }

    signal (SIGCHLD, SIG_IGN);

    while(1)
    {  // main accept() loop
            sin_size = sizeof(struct sockaddr_in);
                if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1)
            {
                    perror("accept");
                    continue;
        }

        printf("server: got connection from %s\n", inet_ntoa(their_addr.sin_addr));

        if (!fork())
        { // this is the child process
                    close(sockfd); // child doesn't need the listener

            char *buf;
            int size = 1000;
            int recvLen = 0;
            buf = (char*)malloc( size );
            int numBytes;
            int i;
            int done = 0;
            while( !done && ((numBytes= recv(new_fd, buf+recvLen, size-recvLen, 0)) >=0) )
            {
                recvLen += numBytes;
                for( i = (recvLen - numBytes); i <recvLen; i++ )
                    if( buf[ i ] == '\0' )
                        done = 1;

                if(( size - recvLen) < 100 )
                {
                    size += 1000;
                    buf = (char *)realloc( buf, size );
                }
            }
            cout <<"Følgende er blevet modtaget: " <<buf <<endl;

            char* message1 = "ord{.|_ord}@ord{.|_ord}.ord";

            if( send( new_fd, message1, strlen( message1 )+1, 0 )== -1 )
                cout <<"Fejl ved afsending af email adressen: "
<<message1 <<endl;

            // SEND EMAIL ADRESSE
            string buffer = buf;

            if( buffer == "request" )
            {    char *message = "navn@domain.landekode";
                //cout <<"Indtast e-mail adresse: ";
                //char *message;
                //gets( message );
                cout <<"Send e-mail adressen: " <<message <<endl <<"Længden: " <<strlen( message ) <<endl;

                if( send( new_fd, message, strlen( message )+1, 0 )== -1 )
                    cout <<"Fejl ved afsending af email adressen: " <<message <<endl;
            }

                    close(new_fd);
                    exit(0);
                }
            close(new_fd);  // parent doesn't need this
        }

        return 0;
}

########

revc er blevet opsådan at den bliver ved med at modtage en char af gangen indtil den møder en nulterminering. Så slipper man får at slukke sende to gange, en med længden af dem som kommer og så selve dataen... Det her revc æder den bare....

Koden kunne dog have været noget bedre.
Avatar billede morw Nybegynder
29. marts 2003 - 21:05 #17
Tak - så kan jeg da hente lidt inspiration. Dog tror jeg mest jeg vil prøve at arbejde videre med select() i stedet for fork() og threads.

Det skulle vel være lidt mere økonomisk med høj load, right?
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