Operating System - Linux
1753925 Members
8579 Online
108810 Solutions
New Discussion юеВ

Re: creation of 64 bit client that will use 32 bit server

 
MurugesanGCT
Advisor

creation of 64 bit client that will use 32 bit server

Hi,

I have a server program (32 bit) which is dependent on 32 bit library libser32.sl

Now I created a 64 bit client binary that needs 64 bit library libser64.sl.

On compiling the 64 bit client program using this library(which is compiled in 64 bit) it is done successfully.

The server SHOULD not be compiled on 64 bit mode.

The client program does the following output

1. Sends message to the server(Successfully)
2. recv fails from the server (Failure) recv() returns -1.


The 64 bit client sends a structure containing "long" to the server.
The "long" is of size 8 bytes on 64 bit and 4 bytes on 32 bit.

The client program needs to be written in 64 bit mode.


To implement 64 bit client, using 64 bit library, is not supporting the expected behaviour.

Question 1:
Is it required to rebuild the server program also in 64 bit. If it is required, rebuild on the server program on 64 bit is not supported.

Question 2:
Can I change the usage of "int" instead of "long" in the structure used for send/recv functions with the server.

Question 3:
Can I do the following steps ?

a) change the library to use "int" instead of "long"
b) compile the library libser32.sl in 32 bit.
c) compile the library libser64.sl in 64 bit.
d) compile the server in 32 bit mode using libser32.sl
e) compile the client in 64 bit mode using libser64.sl

Question 4:
"IS IT NOT SUPPORTED TO CREATE 64 BIT LIBRARY FOR SUPPORTING THE CREATION OF 64 BIT CLIENT LIBRARY" ?
http://www.geocities.com/mukeshgct/
8 REPLIES 8
Dennis Handly
Acclaimed Contributor

Re: creation of 64 bit client that will use 32 bit server

What type of data are you passing back and forth?
Instead of long, you should use int64_t, which is the same in 32 and 64 bit mode.

>1)Is it required to rebuild the server program also in 64 bit.

That would be easier. Otherwise you need to do 2) and 3).

>2) Can I change the usage of "int" instead of "long" in the structure used for send/recv functions with the server.

You can change in it your data, but not for send/rec.

>3) Can I do the following steps?

You may want to use int64_t instead. But what you listed should work, provided the data layout you have is the same.

You should use sizeof on each struct to make sure that matches.

>4) IS IT NOT SUPPORTED TO CREATE 64 BIT LIBRARY FOR SUPPORTING THE CREATION OF 64 BIT CLIENT LIBRARY?

You can do that but you need to make sure the data layouts are the same. The same as if you were writing/reading from disk.
MurugesanGCT
Advisor

Re: creation of 64 bit client that will use 32 bit server

Thank you for this information.
http://www.geocities.com/mukeshgct/
MurugesanGCT
Advisor

Re: creation of 64 bit client that will use 32 bit server

A sample program here

Program containing server as well as the client.

[code]
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAXSIZE 20

#ifdef SIZE
#pragma pack(16)
#endif
struct send
{
//int n; // works fine
long n;
};

class Socket
{
public:
Socket( int );
~Socket( );
int getClientSocket( char[] );
int getServerSocket( );
private:
int port;
int clientFd;
int serverFd;
};


Socket::Socket( int port ) : port( port ), clientFd( -1 ), serverFd( -1 ) { }

Socket::~Socket( )
{
if ( clientFd != -1 )
close( clientFd );
if ( serverFd != -1 )
close( serverFd );
}

int Socket::getClientSocket( char ipName[] )
{

struct hostent* host = gethostbyname( ipName );
if( host == NULL ) {
cerr << "Cannot find hostname." << endl;
return -1;
}

sockaddr_in sendSockAddr;
bzero( (char*)&sendSockAddr, sizeof( sendSockAddr ) );
sendSockAddr.sin_family = AF_INET;
sendSockAddr.sin_addr.s_addr =
inet_addr( inet_ntoa( *(struct in_addr*)*host->h_addr_list ) );
sendSockAddr.sin_port = htons( port );

if( ( clientFd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) {
cerr << "Cannot open a client TCP socket." << endl;
return -1;
}

if ( connect( clientFd, (sockaddr_in*)&sendSockAddr,
sizeof( sendSockAddr ) ) < 0 )
{
cout<<"ERROR : " << errno << " :: " << strerror(errno) << "\n";
return -1;
}

// Connected
return clientFd;
}

int Socket::getServerSocket( ) {
if ( serverFd == -1 ) {
sockaddr_in acceptSockAddr;

if( ( serverFd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) {
cerr << "Cannot open a server TCP socket." << endl;
return -1;
}

bzero( (char*)&acceptSockAddr, sizeof( acceptSockAddr ) );
acceptSockAddr.sin_family = AF_INET;
acceptSockAddr.sin_addr.s_addr = htonl( INADDR_ANY );
acceptSockAddr.sin_port = htons( port );

if( bind( serverFd, (sockaddr_in*)&acceptSockAddr,
sizeof( acceptSockAddr ) ) < 0 ) {
cerr << "Cannot bind the local address to the server socket." << endl;
return -1;
}

listen( serverFd, 5 );
}

int newFd = -1;
sockaddr_in newSockAddr;
int newSockAddrSize = sizeof( newSockAddr );

if( ( newFd =
accept( serverFd, (sockaddr_in*)&newSockAddr, &newSockAddrSize ) ) < 0 ) {
cerr << "Cannot accept from another host." << endl;
return -1;
}
return newFd;
}




const int PORT = 10000 ;

int main( int argc, char *argv[] ) {
struct send snd ;
cout<<"sizeof int: " << sizeof(int) << endl;
cout<<"sizeof long: " << sizeof(long) << endl;
cout<<"sizeof send: " << sizeof(struct send) << endl;
cout<<"sizeof send1: " << sizeof(snd) << endl;
cout<<"main\n\n\n\n";
Socket sock( PORT );
int fd;

if ( argc == 1 ) { // I'm a server
cout<<"\n\nserver\n";
snd.n=0;
while ( true ) {
if ( ( fd = sock.getServerSocket( ) ) == -1 )
return -1;
if(read( fd, &snd, sizeof(snd) ) <= 0)
cout << "error 1 \n" ;
snd.n = ntohl(snd.n) ;
cout << "SERVER RECEIVING FROM CLIENT " << snd.n << endl;
close( fd );
}
}
if ( argc == 2 ) { // I'm a client
snd.n=0;
cout<<"\n\nclient\n";
if ( ( fd = sock.getClientSocket( argv[1] ) ) == -1 )
return -1;
char sendMessage[MAXSIZE];
cout<<"\nEnter any number to be sent to the server : " ;
cin >> snd.n;
snd.n = htonl(snd.n) ;
write( fd, &snd, sizeof(snd) );
}
return 0;
}
[/code]

Makefile

all: client server

client:dins.C
aCC +DAportable +DD64 -g avay.C -o client
server:dins.C
aCC -g +DAportable -DAVAY avay.C -o server
clean:
rm -f server client


OUTPUT FOR SERVER
#############################
$ ./server
sizeof int: 4
sizeof long: 4
sizeof send: 4
sizeof send1: 4
main

server
SERVER RECEIVING FROM CLIENT 0
#############################


OUTPUT FOR CLIENT
#############################
$ ./client localhost
sizeof int: 4
sizeof long: 8
sizeof send: 8
sizeof send1: 8
main


client

Enter any number to be sent to the server : 12
#############################

I Need to resolve this problem.
http://www.geocities.com/mukeshgct/
Dennis Handly
Acclaimed Contributor

Re: creation of 64 bit client that will use 32 bit server

>I Need to resolve this problem.

I told you how. Either you use int as you already said, or you use int64_t:

#include
...

#pragma pack(16)

This is useless, pack only reduces the alignment.

struct send {
//int n; // works fine
#ifdef FIX
int64_t n;
#else
long n;
#endif
};

Your application works fine with this one fix.

#include
This is obsolete and not Standard. Only use and replace bzero by memset.

> aCC +DAportable +DD64 -g avay.C -o client

Remove +DAportable, it conflicts with +DD64.
MurugesanGCT
Advisor

Re: creation of 64 bit client that will use 32 bit server

Thank you for the reply.

I changed the code accordingly
[code]
#include
#include
#include
#include
#include
#include
#include
#include
#include

struct send
{
#ifdef FIX
int64_t n;
#else
long n;
#endif
};

class Socket
{
public:
Socket( int );
~Socket( );
int getClientSocket( char[] );
int getServerSocket( );
private:
int port;
int clientFd;
int serverFd;
};

Socket::Socket( int port ) : port( port ), clientFd( -1 ), serverFd( -1 ) { }

Socket::~Socket( )
{
if ( clientFd != -1 )
close( clientFd );
if ( serverFd != -1 )
close( serverFd );
}

int Socket::getClientSocket( char ipName[] )
{

struct hostent* host = gethostbyname( ipName );
if( host == NULL ) {
cerr << "Cannot find hostname." << endl;
return -1;
}

sockaddr_in sendSockAddr;
memset((char*)&sendSockAddr,'\0',sizeof( sendSockAddr ) );
sendSockAddr.sin_family = AF_INET;
sendSockAddr.sin_addr.s_addr =
inet_addr( inet_ntoa( *(struct in_addr*)*host->h_addr_list ) );
sendSockAddr.sin_port = htons( port );

if( ( clientFd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) {
cerr << "Cannot open a client TCP socket." << endl;
return -1;
}

while ( connect( clientFd, (sockaddr_in*)&sendSockAddr,
sizeof( sendSockAddr ) ) < 0 )
{
cout<<"ERROR : " << errno << " :: " << strerror(errno) << "\n";
return -1;
}

return clientFd;
}

int Socket::getServerSocket( ) {
if ( serverFd == -1 ) {
sockaddr_in acceptSockAddr;

if( ( serverFd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) {
cerr << "Cannot open a server TCP socket." << endl;
return -1;
}

memset( (char*)&acceptSockAddr,'\0', sizeof( acceptSockAddr ) );
acceptSockAddr.sin_family = AF_INET;
acceptSockAddr.sin_addr.s_addr = htonl( INADDR_ANY );
acceptSockAddr.sin_port = htons( port );

if( bind( serverFd, (sockaddr_in*)&acceptSockAddr,
sizeof( acceptSockAddr ) ) < 0 ) {
cerr << "Cannot bind the local address to the server socket." << endl;
return -1;
}

listen( serverFd, 5 );
}

int newFd = -1;
sockaddr_in newSockAddr;
int newSockAddrSize = sizeof( newSockAddr );

if( ( newFd =
accept( serverFd, (sockaddr_in*)&newSockAddr, &newSockAddrSize ) ) < 0 ) {
cerr << "Cannot accept from another host." << endl;
return -1;
}
return newFd;
}




const int PORT = 10000 ;

int main( int argc, char *argv[] ) {
struct send snd ;
cout<<"sizeof int: " << sizeof(int) << endl;
cout<<"sizeof long: " << sizeof(long) << endl;
cout<<"sizeof send: " << sizeof(struct send) << endl;
cout<<"sizeof send1: " << sizeof(snd) << endl;
cout<<"sizeof send1.n: " << sizeof(snd.n) << endl;
cout<<"main\n\n\n\n";
Socket sock( PORT );
int fd;

if ( argc == 1 ) { // I'm a server
cout<<"\n\nserver\n";
snd.n=0;
while ( true ) {
if ( ( fd = sock.getServerSocket( ) ) == -1 )
return -1;
if(read( fd, &snd, sizeof(snd) ) <= 0)
cout << "error 1 \n" ;
snd.n = ntohl(snd.n) ;
cout << "SERVER RECEIVING FROM CLIENT " << snd.n << endl;
close( fd );
}
}
if ( argc == 2 ) { // I'm a client
snd.n=0;
cout<<"\n\nclient\n";
if ( ( fd = sock.getClientSocket( argv[1] ) ) == -1 )
return -1;
cout<<"\nEnter any number to be sent to the server : " ;
cin >> snd.n;
snd.n = htonl(snd.n) ;
write( fd, &snd, sizeof(snd) );
}
return 0;
}
[/code]


and used the following makefile
#####################################
all:server client

client:
aCC +DD64 -g muru.C -o client
server:muru.C
aCC -g muru.C -o server
clean:
rm -f server client
#####################################





Even now also the client sends a number but the server displays that the number received from the client is "0" for the positive numbers and displays "-1" for the negative numbers. I would like to use "int64_t" with the expected behavior on DD64.
http://www.geocities.com/mukeshgct/
Dennis Handly
Acclaimed Contributor

Re: creation of 64 bit client that will use 32 bit server

#ifdef FIX
int64_t n;
#else
long n;
#endif

Sorry, that FIX was an indication of what I changed. To make it work, you need to compile with -DFIX, or remove the false case and just have:
int64_t n;
MurugesanGCT
Advisor

Re: creation of 64 bit client that will use 32 bit server

Thank you for the replies.


[code]
$ make -f muru clean
rm -f server client
$ make -f muru
aCC -g muru.C -o server
/usr/ccs/bin/ld: (Warning) At least one PA 2.0 object file (muru.o) was detected. The linked output may not run on a PA 1.x system.
aCC +DD64 -g muru.C -o client -DFIX
$ ./client localhost
sizeof int: 4
sizeof long: 8
sizeof send: 8
sizeof send1: 8
sizeof send1.n: 8
main





client

Enter any number to be sent to the server : 33



[/code]


[code]
$ cat muru
all:server client

client:
aCC +DD64 -g muru.C -o client -DFIX
server:muru.C
aCC -g muru.C -o server
clean:
rm -f server client
[/code]


I killed the server and ran the server again.
Here goes the server output sir:

[code]
$ ./server
sizeof int: 4
sizeof long: 4
sizeof send: 4
sizeof send1: 4
sizeof send1.n: 4
main

server
SERVER RECEIVING FROM CLIENT 0
[/code]
http://www.geocities.com/mukeshgct/
Dennis Handly
Acclaimed Contributor

Re: creation of 64 bit client that will use 32 bit server

>I killed the server and ran the server again.

I'm not sure why you got the wrong size for your server. Here a gzipped tarfile of the files I changed.
I also had to add -ext to be able to print a long long on PA. I originally did it on IPF.