修改为穿越套接字传递二进制值(而不是文本串),我们将看到,当这样的客户和服务器程序运行在字节序不一样的或者所支持长整数的大小不一致的两个主机上时,工作将失常。
客户程序
#include "unp.h"
struct args{
long arg1;
long arg2;
};
struct result{
long sum;
};
void str_cli(FILE *fp,int sockfd)
{
char sendline[MAXLINE];
struct args args;
struct result result;
while(Fgets(sendline,MAXLINE,fp)!= NULL){
//sscanf把两个参数从文本串转换为二进制数,我们接着调用writen将参数
//结构发送给服务器
if(sscanf(sendline,"%ld%ld",&args.arg1,&args.arg2)!=2){
printf("invalid input: %s",sendline);
continue;
}
Writen(sockfd,&args,sizeof(args));
//调用readn来读回应答,并用printf来输出结果。
if(Readn(sockfd,&result,sizeof(result)) == 0)
err_quit("str_cli:server terminated prematurely");
printf("%ld\n",result.sum);
}
}
int main(int argc,char **argv)
{
int i,sockfd;
struct sockaddr_in servaddr;
if(argc != 2)
err_quit("usage:tcpcli <IPaddress>");
sockfd = Socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
Inet_pton(AF_INET,argv[1],&servaddr.sin_addr);
Connect(sockfd,(SA *) &servaddr,sizeof(servaddr));
str_cli(stdin,sockfd);
exit(0);
}
服务器程序
#include "unp.h"
struct args{
long arg1;
long arg2;
};
struct result{
long sum;
};
void str_echo(int sockfd)
{
ssize_t n;
struct args args;
struct result result;
//调用readn来读入参数,计算并存储两数之和,
//然后调用writen把结果结构发回
for( ; ;){
if((n = Readn(sockfd,&args,sizeof(args)))==0)
return ; /*connection closed by other end*/
result.sum = args.arg1 + args.arg2;
Writen(sockfd,&result,sizeof(result));
}
}
void sig_chld(int signo)
{
pid_t pid;
int stat;
while((pid = waitpid(-1,&stat,WNOHANG)) > 0)
printf("child %d terminated\n",pid);
return;
}
int main(int argc,char **argv)
{
int listenfd,connfd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr,servaddr;
void sig_chld(int);
listenfd = Socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Bind(listenfd,(SA *) &servaddr,sizeof(servaddr));
Listen(listenfd,LISTENQ);
Signal(SIGCHLD,sig_chld);
for( ; ; ){
clilen = sizeof(cliaddr);
if((connfd = accept(listenfd,(SA *) &cliaddr,&clilen)) <0){
if(errno == EINTR)
continue;
else
err_sys("accept error");
}
if((childpid = Fork()) == 0){
Close(listenfd);
str_echo(connfd);
exit(0);
}
Close(connfd);
}
}
结果显示
如果在具有不同体系结构的两个主机上运行同样的客户和服务器程序,那就无法工作了。