sock通信--数据结构的传送

  sock通信中有几个问题必须注意,由于标准的不统一,有的机器使用的大端存储,而有的机器使用的是小端存储(如果对大小端不了解可以上网搜寻一下相关信息). 我们的机器的存储方式各不相同,但是由于历史原因,网络字节序使用的是大端,也就是说,我们要通过网络传输信息到远断,我们要当心了.

  如果明确了传送信息的双方都是相同的存储方式那么还好办,如果传送双方的存储方式不相同或者不一定相同,我们就必须把发送的数据进行相应的格式转换再发送到网络上,直至远端.

  由于网络字节序是大端,那么,我们再发送一个数据结构时,需要把这个结构中的每个成员转换成网络字节序,再发送到远端,而不只是简单的发送这些数据给远端.

  下面是我在发送数据结构时使用的一些例程,希望对涉及到这方面的朋友有帮助.

  在这个例子中,我定义了一个这样的结构体进行传送

 

typedef struct
{
    uint16_t packetlen;
    uint8_t cmdtype;
    uint16_t sessionid;
    uint16_t messageid;
    uint32_t ackinfo;
} ControlHeader;

  定义了这些函数处理结构体中的成员,把他们转换成相应的格式存入缓存中 //
//basic convert funtion declaration
//
void SendUint32_tToBuff(char *buf, uint32_t n);
void SendUint16_tToBuff(char *buf, uint16_t n);
void SendStringToBuff(char *buf, char *str);
uint32_t GetUint32_tFromBuff(char *buf);
uint16_t GetUint16_tFromBuff(char *buf);

//
//structure convert function declaration
//
void init_ControlHeader(uint8_t type, uint16_t sid, uint16_t mid,
uint32_t ack, ControlHeader *pHead);
void sendHeadtobuff(char *buf, ControlHeader *pHead);
void getHeaderfrombuff(void *buff, ControlHeader *p);
int getHeadlen();

  上述定义存放在struct.h文件中,另外写了一个struct.c对上述声明进行定义#include "struct.h" #include <stdio.h> #include <strings.h> //#define TEST 1 // //basic convert funciton definition // void SendUint32_tToBuff(char *buf, uint32_t n) { n = htonl(n); bcopy((char *)&n, buf, sizeof(uint32_t)); } void SendUint16_tToBuff(char *buf, uint16_t n) { n = htons(n); bcopy((char *)&n, buf, sizeof(uint16_t)); } uint32_t GetUint32_tFromBuff(char *buf) { uint32_t n; bcopy(buf, (void *)&n, sizeof(uint32_t)); n = ntohl(n); return n; } uint16_t GetUint16_tFromBuff(char *buf) { uint16_t n; bcopy(buf, (void *)&n, sizeof(uint16_t)); n = ntohs(n); return n; } // //structure convert function declaration // void init_ControlHeader(uint8_t type, uint16_t sid, uint16_t mid, uint32_t ack, ControlHeader *pHead) { pHead->cmdtype = type; pHead->sessionid = sid; pHead->messageid = mid; pHead->ackinfo = ack; } int getHeadlen() { return (sizeof(uint16_t)+sizeof(uint8_t)+sizeof(uint16_t) +sizeof(uint16_t)+sizeof(uint32_t)); } void sendHeadtobuff(char *buf, ControlHeader *pHead) { char *pos = buf; if(buf == NULL) fprintf(stderr, "encouter NULL pointer in sendheadertobuff/n"); else { SendUint16_tToBuff(pos, pHead->packetlen); pos += sizeof(uint16_t); *pos = pHead->cmdtype; pos++; SendUint16_tToBuff(pos, pHead->sessionid); pos += sizeof(uint16_t); SendUint16_tToBuff(pos, pHead->messageid); pos += sizeof(uint16_t); SendUint32_tToBuff(pos, pHead->ackinfo); } } void getHeaderfrombuff(void *pbuff, ControlHeader *p) { char *buf = (void *)pbuff; bcopy(buf, (void *)&p->packetlen, sizeof(uint16_t)); p->packetlen = ntohs(p->packetlen); buf += sizeof(uint16_t); p->cmdtype = *buf; buf += 1; bcopy(buf, (void *)&p->sessionid, sizeof(uint16_t)); p->sessionid = ntohs(p->sessionid); buf += sizeof(uint16_t); bcopy(buf, (void *)&p->messageid, sizeof(uint16_t)); p->messageid = ntohs(p->messageid); buf += sizeof(uint16_t); bcopy(buf, (void *)&p->ackinfo, sizeof(uint32_t)); p->ackinfo = ntohl(p->ackinfo); } #ifdef TEST int main(int argc, char **argv) { ControlHeader myheader; ControlHeader myh; uint8_t type = 1; uint16_t len = 2, sid = 3, mid = 4; uint32_t ackif = 5; char buf[128]; int length = getHeadlen(); init_ControlHeader(type, sid, mid, ackif, &myheader); //see whether init_ControlHeader function right printf("myheader.cmdtype = %d/n", myheader.cmdtype); SendUint32_tToBuff(buf, ackif); //see whether SendUint32_tToBuff function right printf("getuint32_tfrombuff : %d/n", GetUint32_tFromBuff(buf)); SendUint16_tToBuff(buf, len); //see whether SendUint32_tToBuff function right printf("getuint16_tfrombuff : %d/n", GetUint16_tFromBuff(buf)); printf("header length is %d/n", length); sendHeadtobuff(buf, &myheader); //buf[length] = 0; printf("buf is %s/n", buf); getHeaderfrombuff(buf, &myh); printf("myh.cmdtype = %d/n", myh.cmdtype); } #endif  

 

  下面我们写一个简单的网络通信例程,进行试验

  服务器端

#include "unp.h" #include <signal.h> #include "struct.h" #define SRV_PORT 5000 ControlHeader ch; void sig_child(int signo) { pid_t pid; int stat; pid=wait(&stat); printf("child %d terminated/n",pid); return ; } void str_echo(int sockfd) { char buf[1024]; ssize_t n; n=Read(sockfd,buf,MAXLINE); if(n == 0) return ; //printf("bus is : %s/n", buf); getHeaderfrombuff(buf, &ch); printf("ch.cmdtype = %d/n", ch.cmdtype); } int main(int argc,char **argv) { int listenfd,connfd; pid_t childpit; socklen_t socklen; struct sockaddr_in cli_addr,srv_addr; listenfd=Socket(AF_INET,SOCK_STREAM,0); bzero(&srv_addr,sizeof(srv_addr)); srv_addr.sin_family=AF_INET; srv_addr.sin_port=htons(SRV_PORT); srv_addr.sin_addr.s_addr=htonl(INADDR_ANY); Bind(listenfd,(struct sockaddr *)&srv_addr,sizeof(srv_addr)); Listen(listenfd,LISTENQ); if(signal(SIGCHLD,sig_child)==SIG_ERR) err_sys("signal"); /* for(;;) { socklen=sizeof(cli_addr); connfd=Accept(listenfd,(struct sockaddr *)&cli_addr,&socklen); if((childpit=fork())==0) { Close(listenfd); str_echo(connfd); exit(0); } Close(connfd); }*/ socklen=sizeof(cli_addr); connfd=Accept(listenfd,(struct sockaddr *)&cli_addr,&socklen); str_echo(connfd); exit(0); }

 

客户端

#include "unp.h" #include "struct.h" #define SRV_PORT 5000 ControlHeader ch; void str_cli(int sockfd) { ControlHeader ano; ssize_t n; uint8_t type = 1; uint16_t sid = 2; uint16_t mid = 3; uint32_t ack = 4; init_ControlHeader(type, sid, mid, ack, &ch); printf("ch.type = %d", ch.cmdtype); char buf[1024]; sendHeadtobuff(buf, &ch); getHeaderfrombuff(buf, &ano); printf("ano.cmdtype = %d/n", ano.cmdtype); //fgets(buf, 1024, stdin); n = Write(sockfd, buf, getHeadlen()); if(n == 0) { fprintf(stderr, "write size : 0/n"); return ; } } int main(int argc,char **argv) { int sockfd; struct sockaddr_in srv_addr; if(argc!=2) { fprintf(stderr,"usage : a.out IPaddress/n"); exit(1); } sockfd=Socket(AF_INET,SOCK_STREAM,0); bzero(&srv_addr,sizeof(srv_addr)); srv_addr.sin_family=AF_INET; srv_addr.sin_port=htons(SRV_PORT); inet_pton(AF_INET,argv[1],&srv_addr.sin_addr); //remember this Connect(sockfd,(struct sockaddr *)&srv_addr,sizeof(srv_addr)); str_cli(sockfd); exit(0); }

 

完毕.

 

你可能感兴趣的:(数据结构,function,网络,struct,存储,Signal)