如何将不同类型的数据放进一个数组里一起发送
场景: 不同类型的数据如bool、int等需要通过socket发送。
这里提供一个示例,关键部分:
1 const char *sendMsg = "0123456789"; 2 int tLen=strlen(sendMsg); 3 int iLen=0; 4 char * pBuff= new char [100]; 5 *(int*)(pBuff+iLen)= htonl(tLen); 6 7 iLen+=sizeof( int); 8 9 long mydata = 1234; 10 *(long*)(pBuff+iLen) = htonl(mydata); 11 iLen += sizeof(long);
示例中,client向server发送一段字符串、表示长度的int、表示其他数据的long
client.cpp
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <unistd.h> 5 #include <sys/types.h> 6 #include <sys/socket.h> 7 #include <netinet/in.h> 8 #include <arpa/inet.h> 9 #include <errno.h> 10 /* 11 将要发送的长度转成网络字节序,和数据一同放进发送缓冲区 12 int类型是怎么放进char[]里的? 13 int tLen=strlen(sendMsg); 14 int iLen=0; 15 char * pBuff= new char [100]; 16 *(int*)(pBuff+iLen)= htonl(tLen); 17 18 */ 19 20 int MySend( int iSock, char * pchBuf, size_t tLen){ 21 int iThisSend; 22 unsigned int iSended=0; 23 if(tLen == 0) 24 return(0); 25 while(iSended<tLen){ 26 do{ 27 iThisSend = send(iSock, pchBuf, tLen-iSended, 0); 28 } while((iThisSend<0) && (errno==EINTR)); 29 if(iThisSend < 0){ 30 return(iSended); 31 } 32 iSended += iThisSend; 33 pchBuf += iThisSend; 34 } 35 return(tLen); 36 } 37 #define DEFAULT_PORT 6666 38 int main( int argc, char * argv[]){ 39 int connfd = 0; 40 int cLen = 0; 41 struct sockaddr_in client; 42 if(argc < 2){ 43 printf(" Uasge: clientent [server IP address]\n"); 44 return -1; 45 } 46 client.sin_family = AF_INET; 47 client.sin_port = htons(DEFAULT_PORT); 48 client.sin_addr.s_addr = inet_addr(argv[1]); 49 connfd = socket(AF_INET, SOCK_STREAM, 0); 50 if(connfd < 0){ 51 printf("socket() failure!\n" ); 52 return -1; 53 } 54 55 if(connect(connfd, (struct sockaddr*)&client, sizeof(client)) < 0){ 56 printf("connect() failure!\n" ); 57 return -1; 58 } 59 ssize_t writeLen; 60 const char *sendMsg = "0123456789"; 61 int tLen=strlen(sendMsg); 62 printf("tLen:%d\n" ,tLen); 63 int iLen=0; 64 char * pBuff= new char [100]; 65 *(int*)(pBuff+iLen)= htonl(tLen); 66 67 iLen+=sizeof( int); 68 69 long mydata = 1234; 70 //*(bool*)(pBuff+iLen) = htonl(mydata); 71 *(long*)(pBuff+iLen) = htonl(mydata); 72 iLen += sizeof(long); 73 74 75 76 memcpy(pBuff+iLen,sendMsg,tLen); 77 iLen+=tLen; 78 writeLen= MySend(connfd, pBuff, iLen); 79 if (writeLen < 0) { 80 printf("write failed\n" ); 81 close(connfd); 82 return 0; 83 } 84 else{ 85 printf("write sucess, writelen :%d, sendMsg:%s\n",writeLen,sendMsg); 86 } 87 close(connfd); 88 return 0; 89 }
server.cpp
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <sys/wait.h> #include <string.h> #include <errno.h> #include <iostream> int MyRecv( int iSock, char * pchBuf, size_t tCount){ size_t tBytesRead=0; int iThisRead; while(tBytesRead < tCount){ do{ iThisRead = read(iSock, pchBuf, tCount-tBytesRead); } while((iThisRead<0) && (errno==EINTR)); if(iThisRead < 0){ return(iThisRead); }else if (iThisRead == 0) return(tBytesRead); tBytesRead += iThisRead; pchBuf += iThisRead; } } #define DEFAULT_PORT 6666 int main( int argc, char ** argv){ int sockfd,acceptfd; /* 监听socket: sock_fd,数据传输socket: acceptfd */ struct sockaddr_in my_addr; /* 本机地址信息 */ struct sockaddr_in their_addr; /* 客户地址信息 */ unsigned int sin_size, myport=6666, lisnum=10; if ((sockfd = socket(AF_INET , SOCK_STREAM, 0)) == -1) { perror("socket" ); return -1; } printf("socket ok \n"); my_addr.sin_family=AF_INET; my_addr.sin_port=htons(DEFAULT_PORT); my_addr.sin_addr.s_addr = INADDR_ANY; bzero(&(my_addr.sin_zero), 0); if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr )) == -1) { perror("bind" ); return -2; } printf("bind ok \n"); if (listen(sockfd, lisnum) == -1) { perror("listen" ); return -3; } printf("listen ok \n"); char recvMsg[10]; sin_size = sizeof(my_addr); acceptfd = accept(sockfd,(struct sockaddr *)&my_addr,&sin_size); if (acceptfd < 0) { close(sockfd); printf("accept failed\n" ); return -4; } ssize_t readLen = MyRecv(acceptfd, recvMsg, sizeof( int)); if (readLen < 0) { printf("read failed\n" ); return -1; } int len=( int)ntohl(*( int*)recvMsg); printf("len:%d\n",len); ssize_t mydatalen = MyRecv(acceptfd, recvMsg, sizeof(long)); //long mydata=( long)ntohl(*( long*)recvMsg); long mydata=( long)ntohl(*( long*)recvMsg); printf("mydata : %d\n", mydata ); readLen = MyRecv(acceptfd, recvMsg, len); if (readLen < 0) { printf("read failed\n" ); return -1; } recvMsg[len]='\0'; printf("recvMsg:%s\n" ,recvMsg); close(acceptfd); return 0; }
参考:
《后台开发核心技术与应用实践》例6.4