利用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[];
}Node;

服务器代码:

 #include<netinet/in.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h> #define HELLO_WORLD_SERVER_PORT 6666
#define LENGTH_OF_LISTEN_QUEUE 20
#define BUFFER_SIZE 1024 typedef struct
{
int ab;
int num[];
}Node; int main(int argc, char **argv)
{
// set socket's address information
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htons(INADDR_ANY);
server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT); // create a stream socket
int server_socket = socket(PF_INET, SOCK_STREAM, );
if (server_socket < )
{
printf("Create Socket Failed!\n");
exit();
} //bind
if (bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)))
{
printf("Server Bind Port: %d Failed!\n", HELLO_WORLD_SERVER_PORT);
exit();
} // listen
if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE))
{
printf("Server Listen Failed!\n");
exit();
} while()
{
struct sockaddr_in client_addr;
socklen_t length = sizeof(client_addr); int new_server_socket = accept(server_socket, (struct sockaddr*)&client_addr, &length);
if (new_server_socket < )
{
printf("Server Accept Failed!\n");
break;
} Node *myNode=(Node*)malloc(sizeof(Node)); int needRecv=sizeof(Node);
char *buffer=(char*)malloc(needRecv);
int pos=;
int len;
while(pos < needRecv)
{
len = recv(new_server_socket, buffer+pos, BUFFER_SIZE, );
if (len < )
{
printf("Server Recieve Data Failed!\n");
break;
}
pos+=len; }
close(new_server_socket);
memcpy(myNode,buffer,needRecv);
printf("recv over ab=%d num[0]=%d num[999999]=%d\n",myNode->ab,myNode->num[],myNode->num[]);
free(buffer);
free(myNode);
}
close(server_socket); return ;
}

客户端代码:

 #include <sys/types.h>
#include <sys/socket.h> // 包含套接字函数库
#include <stdio.h>
#include <netinet/in.h> // 包含AF_INET相关结构
#include <arpa/inet.h> // 包含AF_INET相关操作的函数
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <pthread.h> #define MYPORT 6666
#define BUFFER_SIZE 1024 typedef struct
{
int ab;
int num[];
}Node; int main()
{
///sockfd
int sock_cli = socket(AF_INET,SOCK_STREAM, ); struct sockaddr_in servaddr;
memset(&servaddr, , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(MYPORT);
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); if (connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr)) < )
{
perror("connect");
exit();
} Node *myNode=(Node*)malloc(sizeof(Node));
myNode->ab=;
myNode->num[]=;
myNode->num[]=; int needSend=sizeof(Node);
char *buffer=(char*)malloc(needSend);
memcpy(buffer,myNode,needSend); int pos=;
int len=;
while(pos < needSend)
{
len=send(sock_cli, buffer+pos, BUFFER_SIZE,);
if(len <= )
{
perror("ERRPR");
break;
}
pos+=len;
}
free(buffer);
free(myNode);
close(sock_cli);
printf("Send over!!!\n");
return ;
}

服务器端执行输出:

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

  1. (转)关于linux中内核编程中结构体的赋值操作(结构体指定初始化)

    网址:http://blog.chinaunix.net/uid-24807808-id-3219820.html 在看linux源码的时候,经常会看到类似于下面的结构体赋值的代码: struct d ...

  2. socket编程——sockaddr_in结构体操作

    sockaddr结构体 sockaddr的缺陷: struct sockaddr 是一个通用地址结构,这是为了统一地址结构的表示方法,统一接口函数,使不同的地址结构可以被bind() , connec ...

  3. inode结构体成员详解

    概述:inode译成中文就是索引节点,它用来存放档案及目录的基本信息,包含时间.档名.使用者及群组等.inode分为内存中的inode和文件系统中的inode,为了避免混淆,我们称前者为VFS ino ...

  4. go语言之行--结构体(struct)详解、链表

    一.struct简介 go语言中没有像类的概念,但是可以通过结构体struct实现oop(面向对象编程).struct的成员(也叫属性或字段)可以是任何类型,如普通类型.复合类型.函数.map.int ...

  5. Solidity的自定义结构体深入详解

    一.结构体定义 结构体,Solidity中的自定义类型.我们可以使用Solidity的关键字struct来进行自定义.结构体内可以包含字符串,整型等基本数据类型,以及数组,映射,结构体等复杂类型.数组 ...

  6. IPv4地址结构体sockaddr_in详解

    sockaddr_in结构体定义 struct sockaddr_in { sa_family_t sin_family; //地址族(Address Family) uint16_t sin_por ...

  7. 结构体指针,C语言结构体指针详解

    结构体指针,可细分为指向结构体变量的指针和指向结构体数组的指针. 指向结构体变量的指针 前面我们通过“结构体变量名.成员名”的方式引用结构体变量中的成员,除了这种方法之外还可以使用指针. 前面讲过,& ...

  8. Linux下的压缩zip,解压缩unzip命令详解及实例

    实例:压缩服务器上当前目录的内容为xxx.zip文件 zip -r xxx.zip ./* 解压zip文件到当前目录 unzip filename.zip ====================== ...

  9. 每天一个linux命令(31): /etc/group文件详解

    Linux /etc/group文件与/etc/passwd和/etc/shadow文件都是有关于系统管理员对用户和用户组管理时相关的文件.linux /etc/group文件是有关于系统管理员对用户 ...

随机推荐

  1. linux查找文件或目录命令

    inux查找文件或目录命令,前提:知道文件或者目录的具体名字,例如:sphinx.conf find 查找  find / -name dirname  查找目录 find -name filenam ...

  2. Java 中线程安全问题

    不好意思,一个国庆假期给我放的都不知道东西南北了,放松,很放松,差一点就弃更了,感谢那些催更的小伙伴们! 虽然没有更新,但是日常的学习还是有的,以后我尽量给大家分享一些通用知识,非技术. 但是本期还是 ...

  3. JXOI2017-2018 解题报告

    链接:JXOI2017-2018 解题报告 代码预览:Github

  4. redis keys 命令

    ## 删除存在的key del key ## 序列体弱给定key,并返回被序列化的值 dump key ## 检查key是否存在 exists key ## 为给定key设置过期时间 expire k ...

  5. 排序算法之冒泡排序Java实现

    排序算法之冒泡排序 舞蹈演示排序: 冒泡排序: http://t.cn/hrf58M 希尔排序:http://t.cn/hrosvb  选择排序:http://t.cn/hros6e  插入排序:ht ...

  6. BZOJ.4316.小C的独立集(仙人掌 DP)

    题目链接 \(Description\) 求一棵仙人掌的最大独立集. \(Solution\) 如果是树,那么 \(f[i][0/1]\) 表示当前点不取/取的最大独立集大小,直接DP即可,即 \(f ...

  7. ngx_lua配置及应用

    一.说明 这里不对lua语言本身及其编译器运行环境等做介绍,以下所有介绍前提对lua相关有所了解. 二.ngx_lua介绍 原理 ngx_lua将Lua嵌入Nginx,可以让Nginx执行Lua脚本, ...

  8. 最小生成树 Prim(普里姆)算法和Kruskal(克鲁斯特尔)算法

    Prim算法 1.概览 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (gra ...

  9. linux中的文件编码及编码修改

    查看文件编码 在Linux中查看文件编码可以通过以下几种方式: 1.在Vim中可以直接查看文件编码 :set fileencoding 即可显示文件编码格式. 如果你只是想查看其它编码格式的文件或者想 ...

  10. wikioi 3130 CYD刷题(背包)

    题目描述 Description 下午,CYD要刷题了,已知CYD有N题可刷,但他只有M分钟的时间,而且他的智慧值为Q,也就是说他只能做出难度小于等于Q的题目.已知每题可得积分Ai,需花费时间Bi,难 ...