Problem mit boost-Threads und Sockets

11/05/2008 - 14:28 von Jens Hornung | Report spam
Hallo,

ich habe ein kleines Problem bei einem Programm, in dem ich in einem
boost-Thread Pakete über einen UDP-Socket annehmen will. Mir ist ehrlich
gesagt nicht ganz klar, wo das Problem liegt. Das merkwürdige an der Sache
ist, dass es hier unter ArchLinux auftaucht, bei einem anderen Rechner mit
Ubuntu (Hardy) aber nicht. Bei beiden ist Boost 1.34.1 installiert.

Per netcat schicke ich von lokal ein UPD-Packet mit den Inhalt "hallo" an
den entsprechenden Port. Die Ausgabe des Programms ist dann:

jens@jadzia:~/work/net$ ./boostthreads
setting socket 3
waiting ...
n: -1 Fehler bei recvfrom()
EINVAL
n: -1
Nachricht (Thread): hallo

waiting ...


Das heißt, das Paket kommt zwar an und ist auch komplett, es wird aber ein
Fehler gemeldet. Wàre schön, wenn jemand ein Tipp hàtte.
Schöne Pfingsttage wünsch ich euch.

Gruß, Jens




#include <iostream>
#include <stdlib.h>
#include <boost/thread/thread.hpp>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <errno.h>


using namespace std;


class Listening
{
public:
Listening() { sd = -1; }

void set_sd(int socket) {
cout << "setting socket " << socket << endl;
sd = socket;
}
void operator()()
{
recv_line();
}

private:
int sd;
void recv_line() {
if(sd == -1) {
return;
}
struct sockaddr_in r_addr;
socklen_t addrsize;
const int max = 512;
char buf[max];
int n;
while(1) {
cout << "waiting ...";
if((n = recvfrom(sd, buf, max, 0, (struct sockaddr*)&r_addr,
&addrsize)) < 0) {
cerr << "n: " << n << " Fehler bei recvfrom()";
switch(errno) {
case EAGAIN:
cout << "EAGAIN";
break;
case EBADF:
cout << "EBADF";
break;
case ECONNREFUSED:
cout << "ECONNREFUSED";
break;
case EFAULT:
cout << "EFAULT";
break;
case EINTR:
cout << "EINTR";
break;
case EINVAL:
cout << "EINVAL";
break;
case ENOMEM:
cout << "ENOMEM";
break;
case ENOTCONN:
cout << "ENOTCONN";
break;
case ENOTSOCK:
cout << "ENOTSOCK";
break;
}
}
cout << "n: " << n << endl;
cout << "Nachricht (Thread): " << buf << endl;
}
}
};


class Siplib
{
public:
Siplib(int p) : port(p) { }

int init_socket();
void run_thread();

private:
int port;
int sd;
Listening listen;
};


int Siplib::init_socket()
{
if((sd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
cerr << "Kann Socket nicht öffnen.";
return -1;
}

struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);

if(bind(sd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
cerr << "Kann Adressen nicht mit Socket verknüpfen.";
close(sd);
return -1;
}
listen.set_sd(sd);
return sd;
}


void Siplib::run_thread()
{
boost::thread th(boost::ref(listen));
}


int main(void) {
int port = 7431;

Siplib sip(port);
sip.init_socket();
sip.run_thread();
while(1) {
sleep(10);
}

return 0;
}
 

Lesen sie die antworten

#1 Christof Meerwald
11/05/2008 - 21:22 | Warnen spam
On Sun, 11 May 2008 14:28:30 +0200, Jens Hornung wrote:
n: -1 Fehler bei recvfrom()
EINVAL


[...]

void recv_line() {
if(sd == -1) {
return;
}
struct sockaddr_in r_addr;
socklen_t addrsize;
const int max = 512;
char buf[max];
int n;
while(1) {
cout << "waiting ...";
if((n = recvfrom(sd, buf, max, 0, (struct sockaddr*)&r_addr,
&addrsize)) < 0) {



addrsize ist ein in/out Parameter - Du solltest recvfrom die Groesse des
sockaddr-Puffers uebergeben (also vor dem recvfrom noch ein "addrsize sizeof(r_addr)" machen).

BTW, valgrind (siehe http://www.valgrind.org) ist bei solchen Sachen immer
einen Versuch wert...


Christof

http://cmeerw.org sip:cmeerw at cmeerw.org
mailto:cmeerw at cmeerw.org xmpp:cmeerw at cmeerw.org

Ähnliche fragen