Linux C Socket编程发送结构体、文件详解及实例
利用Socket发送文件、结构体、数字等,是在Socket编程中经常需要用到的。由于Socket只能发送字符串,所以可以使用发送字符串的方式发送文件、结构体、数字等等。
本文:http://www.cnblogs.com/xudong-bupt/p/3496741.html
1.memcpy
Copy block of memory。内存块拷贝函数,该函数是标准库函数,可以进行二进制拷贝数据。
函数原型: void * memcpy ( void * destination, const void * source, size_t num );
函数说明:从source指向的地址开始拷贝num个字节到以destination开始的地址。其中destination与source指向的数据类型无关。
2.Socket传输
使用memcpy将文件、结构体、数字等,可以转换为char数组,之后进行传输,接收方在使用memcpy将char数组转换为相应的数据。
下面的程序使用Socket传输结构体数据,由客户端传输给服务器端。
传输的结构体为:
typedef struct { int ab; int num[1000000]; }Node;
服务器代码:
1 #include<netinet/in.h> 2 #include<sys/types.h> 3 #include<sys/socket.h> 4 #include<stdio.h> 5 #include<stdlib.h> 6 #include<string.h> 7 8 #define HELLO_WORLD_SERVER_PORT 6666 9 #define LENGTH_OF_LISTEN_QUEUE 20 10 #define BUFFER_SIZE 1024 11 12 typedef struct 13 { 14 int ab; 15 int num[1000000]; 16 }Node; 17 18 int main(int argc, char **argv) 19 { 20 // set socket's address information 21 struct sockaddr_in server_addr; 22 bzero(&server_addr, sizeof(server_addr)); 23 server_addr.sin_family = AF_INET; 24 server_addr.sin_addr.s_addr = htons(INADDR_ANY); 25 server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT); 26 27 // create a stream socket 28 int server_socket = socket(PF_INET, SOCK_STREAM, 0); 29 if (server_socket < 0) 30 { 31 printf("Create Socket Failed!\n"); 32 exit(1); 33 } 34 35 //bind 36 if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr))) 37 { 38 printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT); 39 exit(1); 40 } 41 42 // listen 43 if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE)) 44 { 45 printf("Server Listen Failed!\n"); 46 exit(1); 47 } 48 49 while(1) 50 { 51 struct sockaddr_in client_addr; 52 socklen_t length = sizeof(client_addr); 53 54 int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length); 55 if (new_server_socket < 0) 56 { 57 printf("Server Accept Failed!\n"); 58 break; 59 } 60 61 Node *myNode=(Node*)malloc(sizeof(Node)); 62 63 int needRecv=sizeof(Node); 64 char *buffer=(char*)malloc(needRecv); 65 int pos=0; 66 int len; 67 while(pos < needRecv) 68 { 69 len = recv(new_server_socket, buffer+pos, BUFFER_SIZE, 0); 70 if (len < 0) 71 { 72 printf("Server Recieve Data Failed!\n"); 73 break; 74 } 75 pos+=len; 76 77 } 78 close(new_server_socket); 79 memcpy(myNode,buffer,needRecv); 80 printf("recv over ab=%d num[0]=%d num[999999]=%d\n",myNode->ab,myNode->num[0],myNode->num[999999]); 81 free(buffer); 82 free(myNode); 83 } 84 close(server_socket); 85 86 return 0; 87 }
客户端代码:
1 #include <sys/types.h> 2 #include <sys/socket.h> // 包含套接字函数库 3 #include <stdio.h> 4 #include <netinet/in.h> // 包含AF_INET相关结构 5 #include <arpa/inet.h> // 包含AF_INET相关操作的函数 6 #include <unistd.h> 7 #include <string.h> 8 #include <stdlib.h> 9 #include <fcntl.h> 10 #include <sys/shm.h> 11 #include <pthread.h> 12 13 #define MYPORT 6666 14 #define BUFFER_SIZE 1024 15 16 typedef struct 17 { 18 int ab; 19 int num[1000000]; 20 }Node; 21 22 int main() 23 { 24 ///sockfd 25 int sock_cli = socket(AF_INET,SOCK_STREAM, 0); 26 27 struct sockaddr_in servaddr; 28 memset(&servaddr, 0, sizeof(servaddr)); 29 servaddr.sin_family = AF_INET; 30 servaddr.sin_port = htons(MYPORT); 31 servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 32 33 if (connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) 34 { 35 perror("connect"); 36 exit(1); 37 } 38 39 Node *myNode=(Node*)malloc(sizeof(Node)); 40 myNode->ab=123; 41 myNode->num[0]=110; 42 myNode->num[999999]=99; 43 44 int needSend=sizeof(Node); 45 char *buffer=(char*)malloc(needSend); 46 memcpy(buffer,myNode,needSend); 47 48 int pos=0; 49 int len=0; 50 while(pos < needSend) 51 { 52 len=send(sock_cli, buffer+pos, BUFFER_SIZE,0); 53 if(len <= 0) 54 { 55 perror("ERRPR"); 56 break; 57 } 58 pos+=len; 59 } 60 free(buffer); 61 free(myNode); 62 close(sock_cli); 63 printf("Send over!!!\n"); 64 return 0; 65 }
服务器端执行输出: