Socket学习笔记之二(常用基本函数)

简介:

函数:
u_long htonl(u_long hostlong)
u_short htons(u_short hostshort)
u_long ntohl(u_long netlong)
u_short ntohs(u_short netshort)

这上面四个函数类似,功能相似,都用来转换数据格式。用来实现处理器中short,long数据类型与网络中的转换。在网络中传输均以字节为单位(除了bit外就是最小的单位了)。一个short占两字节,一个long占四个字节。一个short从一台机子传到另外一台机子上要能够还原,则必须统一规定高低字节顺序。在TCP/IP协议规范中short的高位在低字节,低位在高字节。这与有些处理器中或者系统中表示不一样。例如在windows中:
 unsigned short hs = 0x0102;
 unsigned short ns = htons( hs );
 printf( "0x%04x",ns);//ns:0x0201
所以对于网络端口等数据在使用前必须进行统一,例如
unsigned short port = 2088;
m_sockaddr.sin_port = htons( port );
等等。这四个函数,我开始不知道为什么取这些名字总是记不住,后来想明白了
htons表示host to net short,ntohs表示net to host short
htonl表示host to net long,ntohl表示net to host long
这样不需要刻意去记也就明白了。

unsigned long inet_addr(const char* cp);
char* FAR inet_ntoa(struct in_addr in);
 
这两个函数用来把表示ip地址的字符串(如:202.114.14.12)跟表示ip的long或者结构之间转换。
inet_addr得到的是已经统一字节顺序的,可以直接赋值给in_addr里的s_adr,例如:
 char *pHost = "202.114.14.12"
 m_sockaddr.sin_addr.s_addr = inet_addr( pHost );

int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData); 
加载winsock库。返回0表示成功,非0表示错误。第一个参数是版本号,现在最高版本是2.2版,不过Win CE好像只支持1.1版,高位字节表示副版本号,低位字节表示高版本号,所以这里一般就是0x0202或者0x0101或者使用宏定义MAKEWORD(2,2)或者MAKEWORD(1,1),第二个参数是一个与winsock库信息有关的结构,一把不用去管它。在使用winsock前,都必须加载,一般在程序初始化时候做这个事情。一般使用如下:
 WSADATA data;
 if ( WSAStartup(0x0202,&data) != 0 )
 {
  printf("error id: %d",GetLastError());
 }
上面的GetLastError()是使用非常频繁的函数。很多函数的返回值得意义都是表示函数执行是否出错。当winsock的函数发生错误时,用GetLastError()可以得到最后一次发生错误的错误号。在.Net中有个工具:查找错误,输入错误号,得到错误信息。

int gethostname(char* name,int namelen); 
获取主机名。输入参数为缓冲区地址和大小。
struct hostent* FAR gethostbyname(const char* name);
由主机名得到主机信息,可以用来解析域名。需要注意的是MSDN中的一段话“The application must never attempt to modify this structure or to free any of its components. Furthermore, only one copy of this structure is allocated per thread, so the application should copy any information it needs before issuing any other Windows Sockets function calls”这说明了一般用法的时候,要把数据拷贝出来,看看下面代码:
 char   name[255];
 PHOSTENT  phostinfo;
 PHOSTENT  phostinfo1;
 WSADATA data;
 struct in_addr** addrPtr;
 struct in_addr** addrPtr1;

 if ( WSAStartup(0x0202,&data) != 0 )
 {
  printf("error id: %d",GetLastError());
 }

 if( gethostname ( name, sizeof(name)) == 0)
 {
  printf("%s",name);
  if((phostinfo = gethostbyname(name)) != NULL)
  {
   for (addrPtr = (struct in_addr **)phostinfo->h_addr_list;*addrPtr;addrPtr++)
   {//显示我机子的ip
    printf("%s\n", inet_ntoa(**addrPtr));
   }
  }
  else
   printf("error id : %d",GetLastError());
 }
 else
 {
  printf("error id :%d",GetLastError());
 }

 if((phostinfo1 = gethostbyname("bbs.whnet.edu.cn")) != NULL)
 {
  for (addrPtr1 = (struct in_addr **)phostinfo->h_addr_list;*addrPtr1;addrPtr1++)
  {//显示bbs.whnet.edu.cn的ip:202.114.0.248
   printf("%s\n", inet_ntoa(**addrPtr1));
  }
 }
 else
  printf("error id : %d",GetLastError());

 for (addrPtr = (struct in_addr **)phostinfo->h_addr_list;*addrPtr;addrPtr++)
 {//在这里显示的是bbs.whnet.edu.cn的ip:202.114.0.248,不是我机子的ip
  printf("%s\n", inet_ntoa(**addrPtr));
 }

struct HOSTENT* FAR gethostbyaddr(const char* addr,int len,int type);
根据ip地址得到主机信息。这里的ip必须是网络字节顺序的。示例代码:
 PHOSTENT phostinfo2;
 unsigned long ip = inet_addr("127.0.0.1");
 if ( (phostinfo2 = gethostbyaddr((char*)&ip,sizeof(ip),AF_INET)) != NULL)
 {//显示localhost
  printf("host name : %s",phostinfo2->h_name );
 }
 else
  printf("error id : %d",GetLastError());

int getsockname(SOCKET s,struct sockaddr* name,int* namelen); 
这个函数用来的得到socket的本地地址,但是前提是socket必须已经bind或者已经是连接上的。如果socket不是面向连接的话,比如udp,那得socket上有数据才行。
int getpeername(SOCKET s,struct sockaddr* name,int* namelen);
这个函数用来得到socket那一边上的地址,显然socket必须得连接上。“The getpeername function can be used only on a connected socket. For datagram sockets, only the name of a peer specified in a previous connect call will be returned—any name specified by a previous sendto call will not be returned by getpeername.”

至于bind,listen,accept,recv,send等后面学select模型的时候再仔细研究。

目录
相关文章
|
6月前
socket字节序转换与地址转换函数记录
【代码】socket字节序转换与地址转换函数记录。
42 0
|
6月前
socket编程之回声服务器函数的陷阱
由connect函数使用不当导致的小错误 话不多说先看代码:
56 0
|
1月前
|
Python
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输
使用Python的socket库实现客户端到服务器端的图片传输,包括客户端和服务器端的代码实现,以及传输结果的展示。
140 3
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输
|
1月前
|
JSON 数据格式 Python
Socket学习笔记(一):python通过socket实现客户端到服务器端的文件传输
本文介绍了如何使用Python的socket模块实现客户端到服务器端的文件传输,包括客户端发送文件信息和内容,服务器端接收并保存文件的完整过程。
154 1
Socket学习笔记(一):python通过socket实现客户端到服务器端的文件传输
|
6月前
|
存储 算法 网络协议
【探索Linux】P.26(网络编程套接字基本概念—— socket编程接口 | socket编程接口相关函数详细介绍 )
【探索Linux】P.26(网络编程套接字基本概念—— socket编程接口 | socket编程接口相关函数详细介绍 )
69 0
|
前端开发
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之socket发送文本状态2
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之socket发送文本状态2
55 0
|
前端开发
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之自定义指令创建之2
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之自定义指令创建之2
51 0
|
JavaScript 前端开发
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之原生dom导入和移除的技巧2
前端学习笔记202305学习笔记第二十九天-Socket.io文本编辑实时共享之原生dom导入和移除的技巧2
40 0
|
6月前
011.socket函数错误封装处理
·回顾 在 008.一个简单的网络服务器开发----回声服务器中所实现的服务器功能简单,简单到几乎没有什么错误处理,我们知道,系统调用不能保证每次都成功。如 010所示,如果我们因为自己代码写的有些问题那么光是排查错误就够我们受的了。出错的可能千千万,所以我们必须进行出错处理,这样一方面可以保证我们的程序逻辑正常,另一方面可以迅速定位到故障信息。
68 0
|
6月前
socket编程之 connect()函数
再讲了服务器端的函数调用之后,终于来到了我们的客户端编程了(read/write之后会详细介绍的),客户端编程相较于服务器端来说是非常简单的了,在掌握了服务器端编程之后再看客户端编程就会胸有成竹(只需要在学一个函数即可)。
121 0
下一篇
无影云桌面