AIX和sco unix之间使用unix socket编程通讯

扫一扫关注官方微信Unix/Linux下C/C++开发技术概览(上)
Unix/Linux下C/C++开发技术概览(上)
[摘要:起源:http://blog.csdn.net/lovetangtang/archive//582211.aspx 1. 仄台差别简介 Windows战Unix是当前两大支流操纵体系仄台,基于C/C++的开辟职员常常会见临那两个仄台之间的移植的题目。Unix做]
来源:http://blog.csdn.net/lovetangtang/archive//582211.aspx
语言特性的差异,指的是不同操作系统平台中,实现C++/C时的一些细微的差异,忽略这些差异可能会带来一些特别隐蔽的错误。而且可能是致命的错误。所以,了解语言特性的差异,对于在Unix移植来说非常重要。如果考虑系统多多个平台支持,就必须了解在不同平台下语言特性的差异,从开发一开始就把这些因素考虑进去,这样才能最低限度的降低移植的过程中工作量。
字节顺序指的主要是整型变量在内存中的存储方式。在计算机中,数据都是以二进制方式存储的,包括在内存和硬盘中。而计算机又以8位二进制作为一个存储单元。在32位系统中,一个整型的存储需要四个存储单元。也就是说要把一个32位的整数分割成位四段分别进行存储,而每一段的存储位置就是字节顺序的差异。为了清楚的表示每段存储的先后位置,我们用16进制来表示一段的值,下表列出了在Unix系统和Windows系统中整数20000在内存中的情况。
0x00004E20
20 4E 00 00
00 00 4E 20
?网络通信时
?文件存储和读取时
这个问题主要体现在不同平台之间互操作时,在多平台开发过程中,尤其时在网络应用开发的时候,两个平台之间数据交互是非常普遍的,所以这个问题也就显的很普遍。解决这个问题的方法就是交互的双方采用一种相同的数据编码标准,就是数据在传输和存储的时候采用什么方法进行编码,具体的做法有一下几种:
数字转换成字符传进行交互
协商一个同意的字节顺序,根据自己平台的字节顺序还原数据
采用其他标准的编码方式,如ASN1编码
for(int i=0;i&i++)
&&&&&&&&&&&&{
for(int i=0;i&i++)
for(i=0;i&i++)
for(int i=0;i&i++)
for(int i=0;i&i++)
for(int i=0;i&i++)
这是一段正确的代码,虽然在外面已经定义了i,但是在for里面重新定义一个i也没有问题,这是C++的语法所允许的(java里面不允许这样做)。但就是因为这种C++语言的灵活机制,引发了问题的产生。
问题产生源于程序中出现了A_B那样的代码,然后把i的声明拿到了外面。在后期维护的过程中,又在后面增加了一个循环,但是却是按照C的那种方式增加的,这样就产生了问题。请看如下代码:
char str1[10];
char str2[10];
strcpy(str1,””
for(i=0;i&20;i++)
for(int i=0;i&10;i++)
if(str1[i]==0)&
&&&&&memcpy(str2,str1,i);
str2[i]=0;
在C++中,初始化对象的时候系统会自动调用构造函数,因此我们习惯在构造函数中做一些初始化的工作,让自动自动为我们调用初始化的操作。其中,有些对象是静态分配的全局对象,就是在任何函数体外声明的对象,如:
CMyObject g_O
通常情况下,程序启动的时候,系统都会自动调用这个对象的构造函数对这个全局对象进行初始化,但是在某些系统中(SCO Unix),就不想我们期望的那样,也许这是编译器实现的一个bug,但是我们也不能忽视这个问题的存在。对于这种问题,我们可以通过显式创建对象的方法解决,如下:
CMyObject* g_pObject = new CMyO
if(NULL == pVar)
&&&&&&&&…
操作系统特性的差异
文件描述符的限制
升级为64位系统或采用采用64位方式编译程序
使用sys/io.h中的函数操作文件
采用文件池技术,预留一部分文件描述符(3~255之间的),使用freopen函数来重用这些描述符。
进程和线程的限制
网络通信能力的限制
最大等待队列
容错性的影响
图形用户界面
fork&&&&&&& 创建进程
创建一个信的线程
初始化一个线程属性对象
释放一个线程属性对象
终止执行调用的线程
把当前调用线程挂起,直到目标线程结束
设置线程的调度策略和优先级
获得线程的调度策略和优先级
改变/检查调用线程的信号掩码
发送信号到另一个线程
返回当前线程的ID
初始化一个互斥量
初始化互斥量的属性对象
给一个互斥量加锁,如果互斥量已经被别的线程锁定,调用线程挂起,直到别的线程释放
释放互斥量(解锁)
销毁一个互斥量
初始化一个条件变量
初始化一个条件变量的属性对象
阻塞在一个条件变量上
&&&&&&解除下一个线程在条件变量的阻塞
解除所有线程在这个条件变量上的阻塞
销毁一个条件变量
请求结束一个线程
创建一个新线程
终止调用线程
把当前调用线程挂起,直到目标线程结束
用当前线程创建出另一个线程
挂起一个指定的线程
恢复一个被挂起的线程
修改线程的优先级
获得线程的优先级
改变/检查调用线程的信号掩码
发送信号到另一个线程
返回当前线程的ID
标记为主线程
初始化一个互斥量
给一个互斥量加锁,如果互斥量已经被别的线程锁定,调用线程挂起,直到别的线程释放
释放互斥量(解锁)
销毁一个条互斥量
初始化一个条件变量
阻塞在一个条件变量上
解除下一个线程在条件变量的阻塞
解除所有线程在这个条件变量上的阻塞
销毁任何状态的条件变量
初始化一个读写锁
&&&&&&&&&&&&获得一个读写锁的读锁定
获得一个读写锁的写锁定
解锁一个读写锁
初始化一个信号量
销毁一个信号量
&&&&&&&等待获得一个信号量,获得后信号量的值减1,如果当前信号量值位0,当前线程阻塞,支持有别的线程释放信号量
尝试获得一个信号量,获得后信号量的值减1,如果当前信号量值位0,返回失败
释放一个信号量
获得指定信号量的值
System V信号量
对信号量进行一系列的控制
创建一个信号量,成功时返回信号的ID
对信号进行操作
Solaris的本地信号量,更接近于操作系统中我们学到的PV操作的信号灯
初始化一个信号灯(信号量)
销毁一个信号灯
执行信号灯的P操作
跟sema_p类似,当阻塞再这个函数的时候,如果线程收到一个信号,函数退出
尝试执行信号灯的P操作
执行信号灯的V操作
为了方便使用,我在开发的过程中已经把上面常用的函数都封装成了类,兼容Windows和各种常见的Unix系统,而且网上还有很多这方面的代码资源可用。如果感兴趣的话可以向我索要。
感谢关注 Ithao123Unix频道,是专门为互联网人打造的学习交流平台,全面满足互联网人工作与学习需求,更多互联网资讯尽在 IThao123!
Laravel是一套简洁、优雅的PHP Web开发框架(PHP Web Framework)。它可以让你从面条一样杂乱的代码中解脱出来;它可以帮你构建一个完美的网络APP,而且每行代码都可以简洁、富于表达力。
Hadoop是一个由Apache基金会所开发的分布式系统基础架构。
用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。
Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了(relax)POSIX的要求,可以以流的形式访问(streaming access)文件系统中的数据。
Hadoop的框架最核心的设计就是:HDFS和MapReduce。HDFS为海量的数据提供了存储,则MapReduce为海量的数据提供了计算。
产品设计是互联网产品经理的核心能力,一个好的产品经理一定在产品设计方面有扎实的功底,本专题将从互联网产品设计的几个方面谈谈产品设计
随着国内互联网的发展,产品经理岗位需求大幅增加,在国内,从事产品工作的大部分岗位为产品经理,其实现实中,很多从事产品工作的岗位是不能称为产品经理,主要原因是对产品经理的职责不明确,那产品经理的职责有哪些,本专题将详细介绍产品经理的主要职责
IThao123周刊新手园地& & & 硬件问题Linux系统管理Linux网络问题Linux环境编程Linux桌面系统国产LinuxBSD& & & BSD文档中心AIX& & & 新手入门& & & AIX文档中心& & & 资源下载& & & Power高级应用& & & IBM存储AS400Solaris& & & Solaris文档中心HP-UX& & & HP文档中心SCO UNIX& & & SCO文档中心互操作专区IRIXTru64 UNIXMac OS X门户网站运维集群和高可用服务器应用监控和防护虚拟化技术架构设计行业应用和管理服务器及硬件技术& & & 服务器资源下载云计算& & & 云计算文档中心& & & 云计算业界& & & 云计算资源下载存储备份& & & 存储文档中心& & & 存储业界& & & 存储资源下载& & & Symantec技术交流区安全技术网络技术& & & 网络技术文档中心C/C++& & & GUI编程& & & Functional编程内核源码& & & 内核问题移动开发& & & 移动开发技术资料ShellPerlJava& & & Java文档中心PHP& & & php文档中心Python& & & Python文档中心RubyCPU与编译器嵌入式开发驱动开发Web开发VoIP开发技术MySQL& & & MySQL文档中心SybaseOraclePostgreSQLDB2Informix数据仓库与数据挖掘NoSQL技术IT业界新闻与评论IT职业生涯& & & 猎头招聘IT图书与评论& & & CU技术图书大系& & & Linux书友会二手交易下载共享Linux文档专区IT培训与认证& & & 培训交流& & & 认证培训清茶斋投资理财运动地带快乐数码摄影& & & 摄影器材& & & 摄影比赛专区IT爱车族旅游天下站务交流版主会议室博客SNS站务交流区CU活动专区& & & Power活动专区& & & 拍卖交流区频道交流区
白手起家, 积分 41, 距离下一级还需 159 积分
论坛徽章:0
我作为客户端与服务端连接后,每秒接收四组数据,可是隔4、5秒服务端会发一空报文,我用select函数检测,发现有数据可读,但是读回了0个字节,我再select,还是有字符可读,去读又是0个字节返回。这样反复多次,最后读错就断开了与服务端的通讯连接,再重新连接。 而服务器端只是发了一次空报文,我不知道为什么我却读回这么多的空报文,一次select后fd_set读字符集不清空?大家帮帮忙,这是怎么回事啊?谢谢!
&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp
稍有积蓄, 积分 254, 距离下一级还需 246 积分
论坛徽章:0
内核版本?代码?
丰衣足食, 积分 957, 距离下一级还需 43 积分
论坛徽章:0
select现实socket可读但读回0标示连接已关闭.
这个问题man有描述的,不看的吗?
白手起家, 积分 41, 距离下一级还需 159 积分
论坛徽章:0
但是服务端确实发了空报文,没有一个字节,而且服务器端一直发送数据,直到我关闭或者它发送出错,才关闭连接,但是感觉它发送出错的概率不大。
白手起家, 积分 75, 距离下一级还需 125 积分
论坛徽章:0
回复 4楼 lywyh 的帖子
发送空报文是怎么发的。
小富即安, 积分 2895, 距离下一级还需 2105 积分
论坛徽章:0
fd_set应该每次都重置一下吧
而且接收到0字节就是代表连接关闭
呵呵,我都是这样处理的
小富即安, 积分 4599, 距离下一级还需 401 积分
论坛徽章:0
发送了空数据了吧
char buf[128];
memset(buf, 0, sizeof(buf));
.....
write (socket_fd, buf, sizeof(buf));
...
复制代码
这样,在另一端读的时候返回就是0
而且会返回128次
白手起家, 积分 41, 距离下一级还需 159 积分
论坛徽章:0
fd_set应该每次都重置一下吧
而且接收到0字节就是代表连接关闭
呵呵,我都是这样处理的
我每次也都将fd_set重置一下,
但我这实时性要求挺高的,如果发送一次空报文就断了,那肯定不行。
发送了空数据了吧
这样,在另一端读的时候返回就是0
而且会返回128次
但是我用vc编写的测试程序接收,就将空报文丢掉,继续接收,而且每次就接收一个空报文,而不是128次。
vc编写的程序是用异步方式的socket(有fd_READ消息才接收,返回值是0就不处理了),
我的程序是在unix下用select-&recv的。有什么不同吗?
白手起家, 积分 41, 距离下一级还需 159 积分
论坛徽章:0
我的源代码如下,大家看看有问题吗?
int fe_tcp_read_wait(int channel,char *buf,int length,int timer, int log)
& & & & int len,
& & & & fd_set read_temp, err_
& & & & struct timeval wwait,
& & & & if( channel & 0 ) return(-1);
& & & & if( length &= 0 ) return(0);
& & & & for(;
& & & & & & & & wwait.tv_sec=
& & & & & & & & wwait.tv_usec=0;
& & & & & & & & FD_ZERO(&read_temp);
& & & & & & & & FD_SET(channel,&read_temp);
& & & & & & & & status=select(channel+1,&read_temp,(fd_set *)0,(fd_set *)0,&wwait);
& & & & & & & & if(status&0)
& & & & & & & & {
& & & & & & & & & & & & if( (errno==EINTR) || (errno==EAGAIN) )& & & &
& & & & & & & & & & & & return(-1);
& & & & & & & & }
& & & & & & & & if(status==0)
& & & & & & & & {
& & & & & & & & & & & & return(0);
& & & & & & & & }
& & & & & & & &
& & & & if(FD_ISSET(channel,&read_temp))
& & & & & & & & len = fe_tcp_read( channel, (char *)buf, length );
& & & & & & & & if(len&=0)
& & & & & & & & {
& & & & & & & & return(len);
& & & & & & & & }else
& & & & & & & & {
& & & & & & & & & & & & if( log )
& & & & & & & & & & & & {
& & & & & & & & & & & & & & & & fputs( &\nrecv: &, stdout );
& & & & & & & & & & & & & & & & for( status=0; status& status++ )
& & & & & & & & & & & & & & & & {
& & & & & & & & & & & & & & & & & & & & fprintf( stdout, &%02x &, (unsigned char)buf[status] );
& & & & & & & & & & & & & & & & }
& & & & & & & & & & & & & & & & fputs( &\n&, stdout );
& & & & & & & & & & & & }
& & & & & & & & & & & & return(len);
& & & & & & & & }
& & & & }else
& & & & & & & & return(-1);
int fe_tcp_read(int fd,char *ptr,int nbytes)
& & & & int & & & & nleft,
& & & & nleft=
& & & & while(nleft&0)
& & & & & & & & nread=recv(fd,ptr,nleft,0);
& & & & & & & & if(nread&=0)
& & & & & & & & {
& & & & & & & & & & & & if(errno==EINTR) { return(0); }
& & & & & & & & & & & & if( errno == EWOULDBLOCK ) { return(0); }
& & & & & & & & & & & & return(nread);
& & & & & & & & }
& & & & & & & & nleft-=
& & & & & & & & ptr+=
& & & & return(nbytes-nleft);
是不是我需要设置什么属性,如用setsockopt?
小富即安, 积分 4599, 距离下一级还需 401 积分
论坛徽章:0
write部分的代码也贴出来看看博客访问: 859130
博文数量: 7990
注册时间:
鏆傛棤浠嬬粛
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: Unix
unix下编写socket程序的一般步骤 (转)[@more@]下编写socket的一般步骤&章永阳·yesky
  在unix下写socket程序可能是最方便,你只要掌握其一般步骤,就可以松的写出面向传输层的应用。   1、理解几个常用的socket  #include   #include   int socket(int ain,int type,int portocol);  domain指所使用的族(family)可以为AF_UNIX和AF_,一般只用AF_INET(指Internet)type指所用的传输类型,可以为SOCK_STERAM(面向连接的TCP),和SOCK_DGRAM(面向无连接的udp)  int bind(int s,const struct sockaddr *address,size_t address_len);  s为socket返回的描述符  address为协议族名称和其他信息  具体结构为struct sockaddr_in{   short sin_/*协议族   u_short sin_/*端口*/   struct in_addr sin_/*地址*/   char sin_zero[8];  };  int listen(int s,int backlog);  backlog为容许的请求数目  int accept(int s,struct sockaddr *address,int *address_len);  这里的前两个参数同上  addres_len是要传递一个记有结构大小的地址  int connect(int s,struct sockaddr *address,size_t address_len);  这里的参数意义同bind  2.理解建立程序的一般过程  要建立一个处理连接的端程序,首先要调用socket函数创建一个socket,返回一个文件句柄fd,使以后对它的操作就象对普通文件设备一样读写。  由于是服务器端必须对一个断口进行其他机器的请求,所以接下去调用bind函数,传入刚才的fd,定义好地址和端口,由于是要接受来自任何host的连接所以应讲sin_addr赋为INADDR_ANY,port为你所设定的端口。  注意:这里的地址和端口是字节顺序,所以要调用htonl,htons完成主机字节顺序到网络字节的转变  接下来就是监听listen,调用accept接受来自客户端的请求,accpet返回连接后的文件描述符,你就可以用它进行收发信息(对应于read,write)这样的一个过程就是socket->bind->listen->accpet->Read,write而对于客户端则是socket->connect->read,write
3.一个完整的程序  #include   #include   #includeINET in.h>/*包含有htons等函数的头文件*/  #include   #include   void main()   {    int listenfd,        struct sockaddr_in myaddr,            listenfd=socket(AF_INET,SOCK_STREAM,0);    if (listenfd<0)     {      perror("socket error");      exit(-1);     }    myaddr.sin_family=AF_INET;    myaddr.sin_addr.s_addr=htonl(INADDR_ANY);    myaddr.sin_port=htons(8888);    ret=bind(listenfd,(struct sockaddr *)&myaddr,sizeof(myaddr));    if (ret<0)     {      perror("bind error");      exit(-1);     }    listen(listenfd,10);    len=sizeof(struct sockaddr);    while(1)     {      clifd=accept(listenfd,(struct sockaddr*)&cliaddr,&len);       /*注意accept的第三个参数也是地址*/      if(clifd==-1)       {        perror("accept error");                }      printf("connect from %s %dn",inet_ntoa(cliaddr.sin_addr.s_addr),ntohs(cliaddr.sin_port));      switch(pid=fork())       {        case 0: /*子进程*/           close(listenfd);           ;/*子进程进行其他的操作*/           close(clifd);           exit(0);                   case -1:           perror("fork error");                      default:/*父进程*/           close(clifd);                   }       }      }  4.程序说明  该程序的功能是监听8888端口的连接,对所有的对8888端口的连接显示出地址和对方的端口号该程序在 unix下通过,在其他unix和平台请注意inet_ntoa,htons函数所应在的头文件的名称  同时该程序用到了并发的观点,因为accept,read,write均为阻塞(block)的函数,一旦进程block将不能处理其他请求,所以用主进程进行listen,由子进程进行负责对客户端传输数据.   你可以在同一台unix机器用 localhost 8888进行观察程序会输出connect from 127.0.0.1 xxxx
阅读(157) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。

我要回帖

更多关于 unix socket编程 的文章

 

随机推荐