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 }

View Code

客户端代码:

 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 }

View Code

服务器端执行输出:

时间: 2024-09-14 07:05:18

Linux C Socket编程发送结构体、文件详解及实例的相关文章

C语言 结构体数组详解及示例代码_C 语言

所谓结构体数组,是指数组中的每个元素都是一个结构体.在实际应用中,结构体数组常被用来表示一个拥有相同数据结构的群体,比如一个班的学生.一个车间的职工等. 定义结构体数组和定义结构体变量的方式类似,请看下面的例子: struct stu{ char *name; //姓名 int num; //学号 int age; //年龄 char group; //所在小组 float score; //成绩 }class[5]; 表示一个班级有5个学生. 结构体数组在定义的同时也可以初始化,例如: str

c语言中结构体对齐详解

为什么要对齐?     现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐.     对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同.一些平台对某些特定类型的数据只能从某些特定地址开始存取.比如有些架构的CPU在访问 一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保

嵌入式开发C语言位结构体用途详解

在嵌入式开发中,经常需要表示各种系统状态,位结构体的出现大大方便了我们,尤其是在进行一些硬件层操作和数据通信时.但是在使用位结构体的过程中,是否深入思考一下它的相关属性?是否真正用到它的便利性,来提高系统效率? 1.位结构体类型设计 [cpp] view plain copy print? //data structure except for number structure typedef struct symbol_struct { uint_32 SYMBOL_TYPE :5; //da

php 使用fopen函数创建、打开文件详解及实例代码_php实例

php中没有单独的文件创建函数,如果我们想创建函数,可以使用fopen(),fopen()函数字面意思是打开文件,但该函数也有创建文件的功能,当使用 fopen() 函数打开一个文件时,如果文件不存在,则会尝试创建该文件,并返回一个资源. php fopen函数介绍 fopen函数打开文件或者 URL 语法: resource fopen( string filename, string mode ) fopen()将 filename 指定的名字资源绑定到一个流上. 参数: 1. filena

采用thinkphp自带方法生成静态html文件详解_php实例

thinkphp本身自带了一个有效的生成静态页的方法,(该方法在tp2.0的手册上有说明,3.0的手册上没有说明了,不过3.0方法还是存在的.) $this->buildHtml('静态文件', '静态路径','模板文件'); 稍微说明下参数,有些朋友问我这个参数和具体如何使用. 参数一:静态文件,是指生成后的静态文件名,文件保存路径完整的就是:静态路径/静态文件.例如静态文件设置a/index.那么保存的路径就是项 目路径/Html/a/index.html(默认的静态路径在项目路径的Html

php实例分享之通过递归实现删除目录下的所有文件详解_php实例

先贴代码: 复制代码 代码如下: <?phpfunction delFile($dirName){  if ($handle = opendir("$dirName")){  while (($item = readdir($handle))!=false){   if ($item!="." && $item!="..")  {    if ( is_dir( "$dirName/$item" ) )

php 使用fopen函数创建、打开文件详解及实例代码

php中没有单独的文件创建函数,如果我们想创建函数,可以使用fopen(),fopen()函数字面意思是打开文件,但该函数也有创建文件的功能,当使用 fopen() 函数打开一个文件时,如果文件不存在,则会尝试创建该文件,并返回一个资源. php fopen函数介绍 fopen函数打开文件或者 URL 语法: resource fopen( string filename, string mode ) fopen()将 filename 指定的名字资源绑定到一个流上. 参数: 1. filena

socket c c++ 结构体-socket发送结构体问题,无法在服务器端显示完整的结构体

问题描述 socket发送结构体问题,无法在服务器端显示完整的结构体 定义了如下结构体 在发送结构体的时候转换成char *类型 输入了如下学生数据__ 在接收端也进行了数据类型转换,如下 为什么最后的年龄输不出来,而是一串数字,怎么解决? 解决方案 你发送的send是直接发送的student的指针,你需要把整个student的内容存到char数组,然后发送char数组,接收后,也要把char数组memcpy等复制回来 解决方案二: sscanf处有&还能收到数据吗? 解决方案三: 1.你在客户

详解Linux的SOCKET编程_C 语言

本篇文章对Linux的SOCKET编程进行了详细解释文章后面分享了一个编程实例供大家学习. 1. 网络中进程之间如何通信 进程通信的概念最初来源于单机系统.由于每个进程都在自己的地址范围内运行为保证两个相互通信的进程之间既互不干扰又协调一致工作操作系统为进程通信提供了相应设施如 UNIX BSD有管道pipe.命名管道named pipe软中断信号signal UNIX system V有消息message.共享存储区shared memory和信号量semaphore)等. 他们都仅限于用在本