导航:首页 > 编程语言 > javacsocket字节序

javacsocket字节序

发布时间:2025-02-11 14:34:17

❶ 什么是网络字节序,主机字节

网络字节序与主机字节序是计算机内存中数据存储方式的区别,涉及到CPU的字节类型。主机字节序有两种常见类型:Little endian(小端字节序)和Big endian(大端字节序)。Little endian遵循人类直观的逻辑,将低位字节存储在内存地址较小的位置,高位字节则在地址较大处。相反,Big endian将高位字节放在低地址,低位字节放在高地址。

网络字节序在TCP/IP协议中统一规定,与CPU类型和操作系统无关,确保不同主机间数据传输的正确性,采用的是Big endian的排序方式。在编程中,socket函数提供了如htons(unsigned short从主机到网络字节序转换)和ntohl(unsigned long从网络到主机字节序转换)等转换工具。在使用Little endian或Big endian系统时,需要确保代码中的一致性,否则可能会导致数据解析错误,产生bug。

值得注意的是,不同的CPU和操作系统组合,其字节序可能不同,例如x86系统为小端字节序,而PowerPC系统则可能为大端字节序。在编写跨平台或网络程序时,要特别注意处理字节序的转换,以确保数据的正确性。

❷ 什么是网络字节序,主机字节序

网络字节序与主机字节序

不同的CPU有不同的字节序类型 这些字节序是指整数在内存中保存的顺序 这个叫做主机序
最常见的有两种
1. Little endian:将低序字节存储在起始地址
2. Big endian:将高序字节存储在起始地址

LE little-endian
最符合人的思维的字节序
地址低位存储值的低位
地址高位存储值的高位
怎么讲是最符合人的思维的字节序,是因为从人的第一观感来说
低位值小,就应该放在内存地址小的地方,也即内存地址低位
反之,高位值就应该放在内存地址大的地方,也即内存地址高位

BE big-endian
最直观的字节序
地址低位存储值的高位
地址高位存储值的低位
为什么说直观,不要考虑对应关系
只需要把内存地址从左到右按照由低到高的顺序写出
把值按照通常的高位到低位的顺序写出
两者对照,一个字节一个字节的填充进去

例子:在内存中双字0x01020304(DWORD)的存储方式

内存地址
4000 4001 4002 4003
LE 04 03 02 01
BE 01 02 03 04

例子:如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为
big-endian little-endian
0x0000 0x12 0xcd
0x0001 0x23 0xab
0x0002 0xab 0x34
0x0003 0xcd 0x12
x86系列CPU都是little-endian的字节序.

网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式。

为了进行转换 bsd socket提供了转换的函数 有下面四个
htons 把unsigned short类型从主机序转换到网络序
htonl 把unsigned long类型从主机序转换到网络序
ntohs 把unsigned short类型从网络序转换到主机序
ntohl 把unsigned long类型从网络序转换到主机序

在使用little endian的系统中 这些函数会把字节序进行转换
在使用big endian类型的系统中 这些函数会定义成空宏

同样 在网络程序开发时 或是跨平台开发时 也应该注意保证只用一种字节序 不然两方的解释不一样就会产生bug.

注:
1、网络与主机字节转换函数:htons ntohs htonl ntohl (s 就是short l是long h是host n是network)
2、不同的CPU上运行不同的操作系统,字节序也是不同的,参见下表。
处理器 操作系统 字节排序
Alpha 全部 Little endian
HP-PA NT Little endian
HP-PA UNIX Big endian
Intelx86 全部 Little endian <-----x86系统是小端字节序系统
Motorola680x() 全部 Big endian
MIPS NT Little endian
MIPS UNIX Big endian
PowerPC NT Little endian
PowerPC 非NT Big endian <-----PPC系统是大端字节序系统
RS/6000 UNIX Big endian
SPARC UNIX Big endian
IXP1200 ARM核心 全部 Little endian

❸ 如何获得Socket连接客户端的IP地址

如果你测试访问的时候,使用的是 localhost 进行访问的,那么服务器端获得的也就是127.0.0.1,因为localhost是一个环路地址,特殊的.
如果你是通过你的ip地址进行访问的,那么获得的IP地址就会是正确的了.

-------
要通过自己本地的IP进行访问,在控制面板的网络连接里找到本地连接,查看它的属性,并找到"详细信息"按钮,点击后弹出的对话框中IPV4地址就是本地地址.
或打开命令行,输入 ipconfig /all 即可找到本地地址.
在浏览器中通过这个IP地址访问,就不会是127.0.0.1了.

❹ 通过SOCKET句柄获取连接客户端的IP和端口的问题!

暂时还没看出问题来,可以测试一下
1、判断getpeername的返回值,若有错误,把错误代码打印出来;
2、wsprintf函数是针对UNICODE字符的吧?为什么不用sprintf?
3、你的备注里说因为网络传送是低位先传送,正确的应该是网络字节序和主机字节序的问题,在网络上使用网络字节序,是高位先存。主机字节序其实又包括大端和小端,而htons, htonl, inet_addr, inet_ntoa, inet_ntol这些函数就是用于实现主机字节序和网络字节序的转换的,这些函数内部会根据大端还是小端来决定如何将数值转换成网络字节序。

❺ Socket编程

最近也在学 还有一个自己写的C++聊天程序 有点大 下面是C写的
sockets(套接字)编程有三种,流式套接字(SOCK_STREAM),数据报套接字 (SOCK_DGRAM),原始套接字(SOCK_RAW);基于TCP的socket编程是采用的流式套接字(SOCK_STREAM)。基于UDP采 用的数据报套接字(SOCK_DGRAM).
1.TCP流式套接字的编程步骤
在使用之前须链接库函数:工程->设置->Link->输入ws2_32.lib,OK!
服务器端程序:
1、加载套接字库
2、创建套接字(socket)。
3、将套接字绑定到一个本地地址和端口上(bind)。
4、将套接字设为监听模式,准备接收客户请求(listen)。
5、等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)。
6、用返回的套接字和客户端进行通信(send/recv)。
7、返回,等待另一客户请求。
8、关闭套接字。
客户端程序:
1、加载套接字库
2、创建套接字(socket)。
3、向服务器发出连接请求(connect)。
4、和服务器端进行通信(send/recv)。
5、关闭套接字
服务器端代码如下:
#include <Winsock2.h>//加裁头文件
#include <stdio.h>//加载标准输入输出头文件

void main()
{
WORD wVersionRequested;//版本
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 1, 1 );//1.1版本的套接字

err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}//加载套接字库,加裁失败则返回

if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}//如果不是1.1的则退出
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);//创建套接字(socket)。

SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//转换Unsigned short为网络字节序的格式
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);

bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
//将套接字绑定到一个本地地址和端口上(bind)
listen(sockSrv,5);//将套接字设为监听模式,准备接收客户请求(listen)。

SOCKADDR_IN addrClient;//定义地址族
int len=sizeof(SOCKADDR);//初始化这个参数,这个参数必须被初始化

while(1)
{
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);//accept的第三个参数一定要有初始值。
//等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)。
//此时程序在此发生阻塞
char sendBuf[100];
sprintf(sendBuf,"Welcome %s to http://www.sunxin.org",
inet_ntoa(addrClient.sin_addr));
//用返回的套接字和客户端进行通信(send/recv)。
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
char recvBuf[100];
recv(sockConn,recvBuf,100,0);
printf("%s\n",recvBuf);
closesocket(sockConn);//关闭套接字。等待另一个用户请求
}
}
客户端代码如下:
#include <Winsock2.h>
#include <stdio.h>

void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );加载套接字库
if ( err != 0 ) {
return;
}

if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);创建套接字(socket)。

SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));向服务器发出连接请求(connect)。

char recvBuf[100];和服务器端进行通信(send/recv)。
recv(sockClient,recvBuf,100,0);
printf("%s\n",recvBuf);
send(sockClient,"This is lisi",strlen("This is lisi")+1,0);

closesocket(sockClient);关闭套接字。
WSACleanup();//必须调用这个函数清除参数
}

阅读全文

与javacsocket字节序相关的资料

热点内容
lqqm 浏览:828
get一下是什么类型的app 浏览:86
ps改jpg照片文件大小 浏览:898
哪里登录中国工商银行app 浏览:9
文件传输助手如何查找聊天记录 浏览:968
新苹果怎么设置id密码 浏览:618
markdownjs库 浏览:465
收集数据哪个手段好 浏览:40
mysql建的数据库在哪里 浏览:843
win10如何去掉文件夹中的tmp 浏览:578
java处理windows1252 浏览:479
安卓2k播放器 浏览:220
hpwia驱动程序win7 浏览:398
iphone和mac蓝牙连接不上 浏览:844
centos指定用户启动服务配置文件 浏览:176
此exe不是最新版的录像文件 浏览:904
带环文件夹 浏览:78
javascript当前位置 浏览:460
扑克牌接龙编程怎么弄 浏览:914
非诚勿扰灭灯哪个app好 浏览:59

友情链接