linux下socket编程,怎样把文件和文件属性一起发送到服务器端
在socket编程中,可以一次发送多种类型的信息吗?比如说发送文件的同时,把文件的属性获取然后发送过去?使用一个缓冲池吗?要怎么实现?...
在socket编程中,可以一次发送多种类型的信息吗?比如说发送文件的同时,把文件的属性获取然后发送过去?使用一个缓冲池吗?要怎么实现?
展开
2个回答
展开全部
socket可以发送任意类型的数据。socket本身不限制你要发送什么,而是由你自己来定要发什么的。只要你接收端能识别发来的是什么即可。
协议的三个基本要素,语法、语义、同步。比如你用于表示文件属性的结构体或者其他什么数据长度固定是20字节,那么你就在发送文件内容之前把这20字节发送过去,接收端在接收内容之前,固定会先接收20字节并作为文件属性,随后接收到的内容才作为数据存入文件,这样就可以做到了。
关键点就在于自己要定好语法、语义、同步这些,发送端和接收端配合好动作。
协议的三个基本要素,语法、语义、同步。比如你用于表示文件属性的结构体或者其他什么数据长度固定是20字节,那么你就在发送文件内容之前把这20字节发送过去,接收端在接收内容之前,固定会先接收20字节并作为文件属性,随后接收到的内容才作为数据存入文件,这样就可以做到了。
关键点就在于自己要定好语法、语义、同步这些,发送端和接收端配合好动作。
更多追问追答
追问
好像很对的样子~怎么先把这20个字节发送过去呢??
追答
你开了socket,比如tcp,在上面调用send把这20字节发过去即可。
接收端recv就拿到这20字节
然后两边开始传文件内容。
20只是我随口说的,到底多少字节要看你的需要。
另外就是tcp是面向数据流的,tcp协议之上不使用“数据包”的概念:也就是说,它只保证你发送的数据对方能收到,而不管是怎么收到的。例如
第一次发送:abcdefg 第二次发送:hijklmn
第一次接收:abcdefghijklmn
或者
第一次发送:abcdefghijklmn
第一次接收:abcdefg 第二次接收:hijklmn
都是有可能的。这是网上有些人说的什么“粘包”问题。其实人家根本就没有“包”哪来的粘包……
注意区分好哪些是属性哪些是文件内容即可。实际操作中是有可能出现属性和文件内容在一次recv调用中全部来了的情况的。
我给出一种解决方式:
recv不是可以定义要接收多少字节吗,你就在正式接收文件内容之前先收20个字节。如果发现这一次接收不满20字节,比如只收到了10字节,那么下次调用recv的时候,就把要接收的长度定为10字节,如此直到接收满20字节。
p.s.这样做的时候注意每次recv不要都把同一个缓冲区同一个位置送进去了,比如char buf[20]你别每次都
recv(s, buf, 20, 0);
recv(s, buf, 10, 0);
要这样
recv(s, buf, 20, 0);或recv(s, &buf[0], 20, 0);
recv(s, &buf[10], 10, 0);
补充:原来你问的是这个吗……
任何类型的数据,只要不是一个比特一个比特的,其他什么类型都能转成一个char数组的。
比如 int 可以转成 char[4],double可以转成 char[8]
具体说来就是
int a;
char* pa = (char*) &a; //pa[0] ~ pa[sizeof(a) - 1]
或者
double a;
char* pa = (char*) &a; //pa[0] ~ pa[sizeof(a) - 1]
另一边同理
char pa[4];
int a = *(int*)pa;
或者
char pa[8];
double a = *(double*)pa;
展开全部
你要发送什么文件属性呀?你文件发送成功以后,那边接收方就可以看到文件的属性了呀!或者你可以自己做一个协议,比如先接收文件名,再接收文件属性,然后发文件数据,文件属性做个结构体发送过去。如果你非得让属性和文件数据一起发送的话,你可以做一个结构体呀,比如:
typedef struct file_data_attribute
{
int attribute;
char buff[512];
}FILE_ATTRIB;
不用什么缓冲池了吧,发送文件很简单的呀!
typedef struct file_data_attribute
{
int attribute;
char buff[512];
}FILE_ATTRIB;
不用什么缓冲池了吧,发送文件很简单的呀!
追问
文件属性没有发送过去的。要发送的是它的安全属性就是st_mode这个东西。不用一起发送,我知道文件发送的那几个步骤和函数,可是,要怎么把这个类型的数据发送过去呢?刚刚入手,不是很明白呢。
追答
文件发送的过程就是:打开文件fopen,读取文件fread,然后写入缓冲,然后向网络发送数据send。
接收文件的过程就是:创建或打开文件fopen,接收网络上发过来的数据recv,然后写文件fwrite,关闭文件fclose.
比如我要发送一个结构体
typedef struct A
{
int a;
char buff[512];
}TA;
定义一个变量 TA tmp;
然后把这个tmp装好数据,然后就是发送了
在发送的时候我可以这样send(fd, &tmp, sizeof(TA), 0);
接收的函数大概这样写:
{
TA TMP;
memset(TMP, 0, sizeof(TMP));
recv(fd, &TMP, sizeof(TMP), 0);
}
这样你的结构体TMP里面的数据就是从网上发过来的数据了;
其实发送结构体和发送一个char数组是一样的。只需要提供给send或者recv缓冲区的地址就行了。另外传送的时候,缓冲区的填写也是多种多样的,你也可以通过(void*)来传送,接收到以后再强制类型转换就行了!
还有那个mode_t类型,你不要怕那个东西,那就是个unsigned int 类型的。如果你不是每发一个包就得加一个mode_t的话,我建议你这样做:
发送端和接收端先建立一个连接,然后先传送一个结构体,如下:
typedef struct file_info
{
char FileName[64];
mode_t mode;
}FileInfo;
然后发送端先把这个结构体发送过去,告诉对端这个文件名是什么,文件的存取权限是什么。
然后就开始发送文件数据,那就是数据了,每次发送一个buff就可以了!
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询