Linux C Socket编程发送结构体、文件详解及实例
2024-10-19 04:11:24
利用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 ;
}
服务器端执行输出:
最新文章
- 生成模型(Generative Model)与判别模型(Discriminative Model)
- weblogic应用平台常见问题小结
- MSMQ消息队列安装
- 利用WPF绘图
- tornado nginx supervisor
- poj 3013 Big Christmas Tree (最短路径Dijsktra) -- 第一次用优先队列写Dijsktra
- 360回归A股,周鸿祎来给BAT和小米添堵了
- Java禁止浏览器有缓存的源码
- Android底部导航栏(可滑动)----TabLayout+viewPager
- react 脚手架 立即可以写业务 react + react-router-dom + less + axios + antd
- Gym - 101982F Rectangles (扫描线+线段树)
- hadoop记录-浅析Hadoop中的DistCp和FastCopy(转载)
- find a lover
- Web高级 Ajax和跨域CORS
- Linux性能查询常用指令
- python按行遍历一个大文件,最优的语法应该是什么?
- Python3 环境搭建
- jQuery生成QRcode二维码
- 第七周linux内核分析
- 监控网卡流量脚本(Python)
热门文章
- Hadoop整理一(初识Hadoop)
- JAVA 9 新特性
- Mac 上关于TFTP Server 软件的使用
- C# 非模式窗体show()和模式窗体showdialog()的区别
- python 自带的range是不能实现对小数的操作的,如果要对小数操作可以使用numpy
- django项目添加新的app
- Loj10166 数字游戏2
- Codeforces Round #358 (Div. 2) D. Alyona and Strings dp
- 快速定位问题 Request无法获取参数
- java中write(byte[] b)与write(byte[] b,int off,int len)区别