Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Debian, C++ and getservbyname()

0 views
Skip to first unread message

Juha 'Ylis' Ylitalo

unread,
Oct 18, 1996, 3:00:00 AM10/18/96
to

Käytän kotikoneessani Debian-paketteista kasattua Linux:ia (versiona
unstable). Käytönnössä tuo meinaa libc-5.2.18, libg++ 2.7.1-2, g++
2.7.2.1 ja linux kernel 2.0.6.

Kaikki on muuten toiminut ihan mainiosti, mutta kun koitin siirtää
yhden C++ luokan SunOS:sta omaan systeemiin, niin törmäsin sellaiseen
ongelmaan, että getservbyname() antaa järjettömiä arvoja. Laittaisin
tämän kyselyn muuten C/C++ ryhmään, mutta kun tämä luokkaa toimii
aivan hyvin HP/UX 9.x ja SunOS 5.5:n alla.

Esimerkki tapauksena todettakoon:
clientsocket_c :: Connection failed to
:: host = cnnnews(frodo2.ntc.nokia.com)
:: port = nntp(30464)

Tuon porttinumeronhan olisi pitänyt olla 119. Siltä varalta, että
vika olisi koodissa, niin laitan sen artikkelin loppuun.

--
Juha 'Ylis' Ylitalo Juha.Y...@Helsinki.FI <e-mail>
+358 0 773 3664 http://www.helsinki.fi/~jylitalo <WWW>
"Show me a sane man, and I will cure him for you." - Carl Jung

// --------------------------------------------------------------------------
// clientsocket.hh
// --------------------------------------------------------------------------

#ifndef CLIENTSOCKET
#define CLIENTSOCKET

#include <String.h>

class clientSocket_c {
public:
clientSocket_c(String host, String port);
~clientSocket_c(void);

// PUBLIC METHODS
String Read(void);
void Write(const String &line);
private:
// PROHIBITED METHODS
clientSocket_c(const clientSocket_c&);
operator=(clientSocket_c&);

// PRIVATE VARIABLES
int socket_fd;
}; // clientSocket_c

#endif
// --------------------------------------------------------------------------
// clientSocket.cc
// --------------------------------------------------------------------------

#include <assert.h>
#include <iostream.h>
#include <netdb.h>
#include <unistd.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>

#include "clientsocket.hh"

// --------------------------------------------------------------------------
clientSocket_c::clientSocket_c(String host, String port) {
struct hostent *ipAddress = 0;
struct servent *ipPort = 0;
struct sockaddr_in socketAddress;
int connection;

socketAddress.sin_family = AF_INET;
ipAddress = gethostbyname(host);
memcpy(&socketAddress.sin_addr.s_addr,
ipAddress->h_addr_list[0],
ipAddress->h_length);

ipPort = getservbyname(port,0);
socketAddress.sin_port = htons(ipPort->s_port);

socket_fd = socket(AF_INET, SOCK_STREAM, PF_UNSPEC);
assert(socket_fd != -1);
connection = connect(socket_fd,
(struct sockaddr *)&socketAddress,
sizeof(socketAddress));
if (connection == -1) {
cerr << "clientsocket_c :: Connection failed to" << endl;
cerr << " :: host = " << host;
cerr << "(" << ipAddress->h_name << ")" << endl;
cerr << " :: port = " << port;
cerr << "(" << ipPort->s_port << ")" << endl;
exit(1);
} // if
assert(connection != -1);
} // clientSocket_c::clientSocket_c

// --------------------------------------------------------------------------
clientSocket_c::~clientSocket_c(void) {
shutdown(socket_fd, 2);
close(socket_fd);
} // clientSocket_c::~clientSocket_c

// --------------------------------------------------------------------------
String clientSocket_c::Read(void) {
String line = "";
char received[2];

received[0] = received[1] = '\0';
while (received[0] != '\n') {
line += received;
read(socket_fd, received,1);
} // while
return(line);
} // clientSocket_c::Read

// --------------------------------------------------------------------------
void clientSocket_c::Write(const String &line) {
int len, sent;
String output = line + "\n";

len = output.length();
sent = write(socket_fd, output, len);
assert(sent == len);
} // clientSocket_c::Write

#include <stdio.h>
#include <iostream.h>
#include "clientsocket.hh"

void main(void) {
char buf[1024];
String str;
clientSocket_c socket("news","nntp");

while (1) {
str = socket.Read();
cerr << "+" << str << endl << "<" << flush;
buf[0] = '\0';
gets(buf);
str = buf;
if (str.length() > 0)
socket.Write(str);
} // while
}

Jani Jaakkola

unread,
Oct 18, 1996, 3:00:00 AM10/18/96
to Juha 'Ylis' Ylitalo

Hänen pyhyytensä Juha.Y...@Helsinki.fi (Juha 'Ylis' Ylitalo)
tuotti sormenpäillään seuraavat valaistuneet sanat:

> Kaikki on muuten toiminut ihan mainiosti, mutta kun koitin siirtää
> yhden C++ luokan SunOS:sta omaan systeemiin, niin törmäsin sellaiseen
> ongelmaan, että getservbyname() antaa järjettömiä arvoja. Laittaisin
> tämän kyselyn muuten C/C++ ryhmään, mutta kun tämä luokkaa toimii
> aivan hyvin HP/UX 9.x ja SunOS 5.5:n alla.

Tämä johtuu siitä, että SunOS:ssä sattu toimimaan oikein, koska SunOS:ssän
bittijärjestys on sama kuin verkossa yleensä.

> Esimerkki tapauksena todettakoon:
> clientsocket_c :: Connection failed to
> :: host = cnnnews(frodo2.ntc.nokia.com)
> :: port = nntp(30464)
>
> Tuon porttinumeronhan olisi pitänyt olla 119. Siltä varalta, että
> vika olisi koodissa, niin laitan sen artikkelin loppuun.

119*256=30464 eli tavut on menneet sekaisin.


>
> ipPort = getservbyname(port,0);
> socketAddress.sin_port = htons(ipPort->s_port);

^^^^^
Tuossa se on. Otteita getservbyname:n manuaalisivuilta:

The getservbyname() function returns a servent structure
for the line from /etc/services that matches the service
name using protocol proto.
<CLIP>
The servent structure is defined in <netdb.h> as follows:

struct servent {
char *s_name; /* official service name */
char **s_aliases; /* alias list */
int s_port; /* port number */
char *s_proto; /* protocol to use */
}
<CLIP>
s_port The port number for the service given in network
byte order.

htons() ei siinä SunOS koneessa tee mitään, ei siis myöskään sotke
bittijärjestystä. Linux koneessa, joka pyötii i*86 arkkitehtuurissa
se vääntää shortin tavut toiseen järjestykseen.

--
------ Jani Jaakkola , jjaa...@cs.helsinki.fi ------
------ http://www.cs.helsinki.fi/~jjaakkol ------

0 new messages