Xref: utzoo comp.sys.encore:607 comp.unix.questions:21942 Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!samsung!think!snorkelwacker!bloom-beacon!athena.mit.edu!jik From: jik@athena.mit.edu (Jonathan I. Kamens) Newsgroups: comp.sys.encore,comp.unix.questions Subject: Re: getsockname problem ?? Message-ID: <1990May3.233332.5956@athena.mit.edu> Date: 3 May 90 23:33:32 GMT References: <7889@rouge.usl.edu> Sender: news@athena.mit.edu (News system) Reply-To: jik@athena.mit.edu (Jonathan I. Kamens) Organization: Massachusetts Institute of Technology Lines: 51 (NOTE: I don't read comp.sys.encore, so I don't know if this question has already been answered. Also, I feel that the question is of general interest to Unix programmers, and reveals something important about using network code on *any* Unix platform, so I am posting to both comp.sys.encore and comp.unix.questions.) In article <7889@rouge.usl.edu>, pcb@gator.cacs.usl.edu (Peter C. Bahrs) writes: |> The code makes a call to : getsockname (socket, (struct sockaddr*) ptr, &len) |> where ptr is of type sockaddr_in. This seems to work fine on the SUN and |> on the VAX and the RT. I am trying to reference the field : |> ptr->sin_port which is a numeric. I want to: |> sprintf (buff, "%d", ptr->sin_port); |> Like I said, it works fine on SUN and VAX but puts some wierd stuff in their |> for the Encore. The weird stuff is not the same port ID as was created. |> I doing something non portable? The important thing to realize here is that port numbers and addresses are stored in struct sockaddr_in structures in network byte order. Therefore, *whenever* you want to use the sin_port or sin_addr.s_addr component of a sockaddr_on, you have to convert it from network byte order to host byte order, and whenever you want to store a value into the sin_port field of the sockaddr_in (or store a constant address into the sin_addr.s_addr field, although this type of thing is frowned upon, since you should use gethostbyname() and then assign the return value directly into the sin_addr.s_addr field), you have to convert the number from host byte order into network byte order before doing the assignment. The functions you use to do this are htons(), htonl(), ntohs() and ntohl(). The first two convert host shorts and host longs to network shorts and network longs, and the second two do the opposite. There should be man pages for these functions on your systems. A couple notes: 1. Theoretically, byte order may not be all that makes your machine's number representation different from network byte order representation, and the hton* and ntoh* functions will take care of other differences, but *I've* never worked on a machine where anything besides byte order matters :-). 2. On machines where network byte order and host byte order are the same, the four functions I've mentioned are supposed to be declared as null macros in the header file that declares them (on my system, they're declared in ). Jonathan Kamens USnail: MIT Project Athena 11 Ashford Terrace jik@Athena.MIT.EDU Allston, MA 02134 Office: 617-253-8495 Home: 617-782-0710