Avatar billede morw Nybegynder
03. april 2003 - 17:20 Der er 3 kommentarer og
2 løsninger

Fra sting(char array) alm string i c++ (sockets)

Jeg er ved at strikke en server sammen, og har lidt problemer med det jeg får fra recv().

Jeg ved ikke rigtig hvordan jeg får den buffer (char array der er i recv() over i min alm. c++ string.

problem1: (hvordan smider jeg over i alm string (ligger i et map))

alle[it->first].buffer += buf;
           
problem2: (hvordan udskriver jeg?)
cout << "buf: " <<  buf << endl;
           
Skal lige siges at det compiler fint. Blot er det noget volapyk der kommer ud på serveren:

> ./server
Server startet!
1
selectserver: new connection from 192.168.0.4 on socket 4
2
selectserver: new connection from 192.168.0.4 on socket 5
3
buf: f:(Ô3(Ô3(
alt: f:(Ô3(Ô3(
3
PuTTYPuTTYselectserver: socket 5 hung up
2
selectserver: socket 4 hung up
1
^C
>



Hele koden:

#include <map>
#include <iostream>
#include <string>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace std;

// port we're listening on
#define PORT 7913 

string hent(string *s)
{
  string temp;

  // find første \n
  unsigned int f = s->find("\n",0);

  if(f != string::npos)
  {

    // temp
    temp = s->substr(0, f);

    // resten
    *s = s->substr(f+1, s->size() - f -1);
  }
  else
  {
    temp = "";
  }

  //return
  return temp;
}

// struct
struct Deltager_info
{
  int fd_socket;
  string nick;
  int mode;
  string buffer;
};


int main()
{

  // erklær
  string ind;
  map<int, Deltager_info> alle;
 
  // fra chat
  fd_set master;  // master file descriptor list
  fd_set read_fds; // temp file descriptor list for select()
  struct sockaddr_in myaddr;    // server address
  struct sockaddr_in remoteaddr; // client address
  int listener;    // listening socket descriptor
  int newfd;        // newly accept()ed socket descriptor
  char buf[256];
  int nbytes;
  int yes=1;        // for setsockopt() SO_REUSEADDR, below
  socklen_t addrlen;
  int fdmax;


  // start
  cout << "Server startet!" << endl;

  // clear the master and temp sets
  FD_ZERO(&master); 
  FD_ZERO(&read_fds);
 
  // get the listener
  if((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    exit(1);
  }
 
  // lose the pesky "address already in use" error message
  if(setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
    perror("setsockopt");
    exit(1);
  }
     
  // bind
  myaddr.sin_family = AF_INET;
  myaddr.sin_addr.s_addr = INADDR_ANY;
  myaddr.sin_port = htons(PORT);
  memset(&(myaddr.sin_zero), '\0', 8);

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

  // listen
  if (listen(listener, 10) == -1) {
    perror("listen");
    exit(1);
  }

  // add the listener to the master set
  FD_SET(listener, &master);
  fdmax = listener; // so far, it's this one

  // listener -> map   
  alle[listener].nick = "lytter";
  alle[listener].mode = 100;
  alle[listener].buffer = "";
 
  // hovedloop
  while(1) {
   
    // copy it
    read_fds = master;
   
    cout <<  alle.size() << endl;
    // select
    if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
      perror("select");
      exit(1);
    }    
     
    // loop gennem sockets
    for(map<int, Deltager_info>::iterator it = alle.begin(); it != alle.end(); ++it)
    {
      // test om socket er ok
      if (FD_ISSET(it->first, &read_fds))
      {
        // er det lytteren
        if (it->first == listener)
        {
          // handle new connections
          addrlen = sizeof(remoteaddr);
         
          // hent ny socket - udskriv hvis fejl
          if ((newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen)) == -1) {
            perror("accept");
          }
          else // ny socket ok
          {
            // add to master set           
            FD_SET(newfd, &master);
           
            // keep track of the maximum
            if (newfd > fdmax) {   
              fdmax = newfd;
            }
           
            // indsæt i map
            alle[newfd].mode = 1; // 1 = venter på brugernavn
           
            printf("selectserver: new connection from %s on socket %d\n", inet_ntoa(remoteaddr.sin_addr), newfd);
          }
         
        }
        else // det er ikke lytteren = alm client
        {
          // handle data from a client   
          if ((nbytes = recv(it->first, buf, sizeof(buf), 0)) <= 0)
          {
            // got error or connection closed by client
            if (nbytes == 0)
            {
              // connection closed
              printf("selectserver: socket %d hung up\n", it->first);
            }
            else
            {
              perror("recv");
            }
           
            // farvel
            close(it->first); // bye!
           
            // remove from master set
            FD_CLR(it->first, &master);
           
            // fjern fra map
            alle.erase(it->first);
          }
          else // rigtig data fra client
          {
            // gem ny tekst i buffer
            alle[it->first].buffer += buf;
           
            // udskriv ny buf
            cout << "buf: " <<  buf << endl;
           
            // udskriv buffer
            cout << "alt: " <<  alle[it->first].buffer << endl;
          } // data fra client
        } // ikke lytteren
      } // if socket ok       
    } // socket loop
  } // hovedloop     

  // slut
  return 0;
}
Avatar billede arne_v Ekspert
03. april 2003 - 17:24 #1
char array -> STL string : almidnelig assignment
STL string -> char array : c_str metode
Avatar billede arne_v Ekspert
03. april 2003 - 17:25 #2
Både STL string og char array burde kunne <<'s ud i cout.
Avatar billede morw Nybegynder
03. april 2003 - 17:27 #3
Men måske er bug kun en adresse erller hva?

alle[it->first].buffer += buf;

giver i ald fald ikek det ønskede resultat.

kan du se fejlen?
Avatar billede morw Nybegynder
03. april 2003 - 17:29 #4
Her indtaster jeg abc:

> ./server
Server startet!
1
selectserver: new connection from 192.168.0.4 on socket 4
2
buf: a:(Ô3(Ô3(
alt: a:(Ô3(Ô3(
2
PuTTYPuTTYbuf: b:(Ô3(Ô3(
alt: a:(Ô3(Ô3(b:(Ô3(Ô3(
2
PuTTYPuTTYPuTTYbuf: c:(Ô3(Ô3(
alt: a:(Ô3(Ô3(b:(Ô3(Ô3(c:(Ô3(Ô3(
2
PuTTYPuTTYPuTTYPuTTYselectserver: socket 4 hung up
1


Det kommer i buffer - der sker bare en masse andet
Avatar billede morw Nybegynder
03. april 2003 - 17:40 #5
Skulle bruge *buf i stedet for buf.

Er dog ikke nået til det i min bog endnu, så jeg ved ikke rigtig hvornår man skal bruge dem.

> ./server
Server startet!
1
selectserver: new connection from 192.168.0.4 on socket 4
2
buf: a
alt: a
2
buf: b
alt: ab
2
buf: c
alt: abc
2
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