如何用socket传输unsigned char *的数据

MiddleNightBroken 2012-07-30 03:10:59
int send(SOCKET s,const char *buff,int len,int flags);
int recv(SOCKET s,const char *buff,int len,int flags);
我也不太懂socket,新手一个。
因为要用于工业,我要传输电压的值之类的,请问怎么样可以传送BYTE *的,不要说什么强制转化,会损失数据的。请教了~!~!~!~!
...全文
1197 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
连裆裤 2014-07-23
  • 打赏
  • 举报
回复
学习了 原来是这样啊
zyplayer-doc 2013-09-14
  • 打赏
  • 举报
回复
引用 楼主 sococome 的回复:
int send(SOCKET s,const char *buff,int len,int flags); int recv(SOCKET s,const char *buff,int len,int flags); 我也不太懂socket,新手一个。 因为要用于工业,我要传输电压的值之类的,请问怎么样可以传送BYTE *的,不要说什么强制转化,会损失数据的。请教了~!~!~!~!
妹啊。。。unsigned char型的数据是二进制形式的,而char 则是以 \0 为结束标志,如果强转则会把数据从 \0 那里截断,既然是要send 怎么可以把数据截断?。。。我在读取二进制文件时也遇到这个问题了。。。比如读取一个EXE或者图片文件时。但send函数只能用 const char *型的数据。。。
songjinn 2012-08-22
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
另外,对指针强转,是不更改任何内存中的数据的,哪来的什么损失数据之说。
对指针强转,只是为了让编译通过面而已。

比如你要发送一个int数据,则这样强转:int i; send((const char*)&i, ...);
不能是:int i; char c = (char) i; send((const char*) &c, ...);
后者才会损失数据。
[/Quote]
楼上正解!!!!!
youngwolf 2012-07-30
  • 打赏
  • 举报
回复
另外,对指针强转,是不更改任何内存中的数据的,哪来的什么损失数据之说。
对指针强转,只是为了让编译通过面而已。

比如你要发送一个int数据,则这样强转:int i; send((const char*)&i, ...);
不能是:int i; char c = (char) i; send((const char*) &c, ...);
后者才会损失数据。
youngwolf 2012-07-30
  • 打赏
  • 举报
回复
基本上,c/c++里面的所有基本数据类型,都是给编程的人看的,编译成机器语言之后,就没有什么数据类型(可能就只分整型和浮点型了)了,比如:
int a = 1;
char b = 2;

第一句告诉机器,把a代表的内存(长度为size(int)),写入1;
第二句告诉机器,把b代表的内存(长度为size(char)),写入2;

那为什么还要数据类型呢?一是cpu本身支持32位操作;二是我们还有范围的要求(char范围太小了),你完全可以用char[4]来当然一个int,加的时候,你自己去处理进位(只是这样太笨了,cpu已经有的功能,你自己实现了一遍)
youngwolf 2012-07-30
  • 打赏
  • 举报
回复 2
网络编程中,传送的是一片内存里面的数据,这些数据是无类型的(在socket看来),所以linux下,recv接受的参数是const void*,这样省去了开发者强转的步骤。

那windows下为什么要用const char*呢?
我想这是历史遗留问题,不管是windows还是linux,其内部仍然是const char*,不同的是,linux接受const void*参数,在使用的时候,它自己转为const char*而已。为什么呢,因为发送数据的过程中,可能涉及到指针的移动,对一个const void*做移动操作(比如加加)是不允许的(或者说没有这个语义),所以内核在处理缓存的时候,必须的是占8位的某个数据的指针(如果占16位,那就不好处理用户发送单数字节长度的消息了),所以内核完全可以采用const unsigned char*,至于为什么采用了const char*,完全是一个历史遗留。

send函数用了这么多年,按照楼主的意思,只能发送字符串了?你也说了,你是新手,那就要注意你的语气了,不要说什么“不要告诉你怎样怎样的”!

send函数虽然接受一个const char*参数,但它不会把这个参数当成普通意义上的字符串的,普通意义上的字符串,是c语言的约定(以\0为结束符),真正起作用的,是一个指针加一个长度,这样唯一的确定了一片内存。
lqfcu2 2012-07-30
  • 打赏
  • 举报
回复
其实楼主要搞明白,传输的都是字节数据,没什么类型之分的
firendlys 2012-07-30
  • 打赏
  • 举报
回复 3
什么叫"强制转化会损失数据"???在计算机内部,没有类型这个概念,也就不存在是否损失数据这个问题.
所谓的强制转换,其实就是告诉编译器,将这个值按照什么方式进行解释.而这个过程是并不会修改数据的.


对于c/c++来说, char 和 unsigned char 其实就是一样的(都是8bit,1个字节),所以两者在任何地方都可以说是完全等效的.
至于BYTE,其实也就是 unsigned char 而已.

知道了这些,还需要考虑么?

假设你发送的数据是 BYTE* b;
那么发送的时候, send(SOCKET , (const char *)b , int,int);就行了,传输的数据是不会出错的.

至于接收,同样定义一个 BYTE *b ,不过要预先分配好空间, 比如 BYTE*b=new BYTE[100];
然后, recv(SOCKET , (char*)b , int , int ) 就是了.得到的 b 的数据,就是你发送过来的数据了.
网络编程-PING程序设计实验指导书 一.实验目的 (1)熟悉原始套接字编程。 (2)了解网络的结构。 (3)了解网络传输底层协议。 二.实验要求 PING程序是用于测试网络连通性的程序。要求在WINDOWS环境下实现基本的PING程序 功能. 在命令提示符下输入: PING ***.***.***.*** 其中***为目的主机的IP地址,不要求支持域名,对是否带有开关变量也不做要求。 不带开关变量时,要求返回4次响应。 返回信息的格式: REPLY FROM ***.***.***.*** 或 REQUEST TimeOut (无法PING通的情况) 三.实验原理 1、PING的工作原理 ping 程序是用来探测主机到主机之间是否可通信,如果不能ping到某台主机,表明不能和这 台主机建立连接。ping 使用的是ICMP协议,它发送ICMP回送请求消息给目的主机。ICMP协议规定:目的主机必 须返回ICMP回送应答消息给源主机。如果源主机在一定时间内收到应答,则认为主机可 达。 ICMP协议通过IP协议发送的,IP协议是一种无连接的,不可靠的数据包协议。因此, 保证数据送达的工作应该由其他的模块来完成。其中一个重要的模块就是ICMP(网络控制 报文)协议。 当传送IP数据包发生错误--比如主机不可达,路由不可达等等,ICMP协议将会把错 误信息封包,然后传送回给主机。给主机一个处理错误的机会,这也就是为什么说建立 在IP层以上的协议是可能做到安全的原因。ICMP数据包由8bit的错误类型和8bit的代码 和16bit的校验和组成。而前 16bit就组成了ICMP所要传递的信息。 PING利用ICMP协议包来侦测另一个主机是否可达。原理是用类型码为0的ICMP发请求 ,受到请求的主机则用类型码为8的ICMP回应。ping程序来计算间隔时间,并计算有多少 个包被送达。用户就可以判断网络大致的情况。 IP数据报 TCP/IP协议定义了一个在因特网上传输的包, 称为IP数据报(IP datagram). 这是一个与硬件无关的虚拟包, 由包头和数据两部分组成, 包头中的源地址和目的地址都是IP协议地址. ICMP TCP/IP组件包括一个ICMP(Internet Control Message Protocol)协议, 该协议定义了的报文类型: Echo,Echo Reply,用于ping程序的基本实现 下图是ICMP报文的传送: 2、RAW模式的SOCKET编程 PING程序是面向用户的应用程序,该程序使用ICMP的封装机制,通过IP协议来工作。为 了实现直接对IP和ICMP包进行操作,实验中使用RAW模式的SOCKET编程。 熟悉SOCKET的编程,包括基本的系统调用如SOCKET、BIND等. 3、具体内容 (1) 定义数据结构 需要定义好IP数据报、ICMP包等相关的数据结构 (2) 程序实现 在WINDOWS环境下实现PING程序 四. 实验步骤和注意事项 1、 熟悉IP以及ICMP协议的工作机制 2、 熟悉RAW模式的SOCKET编程 3、编写PING的实现程序 4、编译环境中需要包括SOCKET库 WS2_32.lib 5、 在模拟实现环境下调试并运行自己编写的PING程序 6、最后提交源程序,撰写实验报告 初步流程图 具体步骤 1、定义IP头和ICMP头 该程序定义自己的IP头和ICMP头数据结构,代码如下: //IP首部数据结构 typedef struct iphdr { unsigned int h_len : 4 ; //首部长度 unsigned int version : 4 ; //版本 unsigned char tos ; //服务类型 unsigned short total_len ; //报文总长度 unsigned short ident ; //标识 unsigned short frag_and_flags ; //偏移量 unsigned char ttl ; //寿命 unsigned char proto ; //协议 unsigned short checksum ;// 首部校验和 unsigned int sourceIP ;// 源站IP unsigned int destIP ;// 目的站IP }; //ICMP首部数据结构 typedef struct icmphdr { BYTE i_type ; //类型 BYTE i_code ; //代码 USHORT i_cksum ; //首部校验和 USHORT i_id ; //标识 USHORT i_seq ; //序列号 ULONG timestamp ; //时间戳 }; 2.定义变量 WSADATA wsaDa

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧