开发者社区> 杨粼波> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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模型的时候再仔细研究。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
网络编程:socket 概述|学习笔记
快速学习网络编程:socket 概述
0 0
Python编程:socket模块
Python编程:socket模块
0 0
C#Socket编程笔记,Socket 详解,入门简单
目录 一,网络基础 二,Socket 对象 三,Bind() 绑定与 Connect() 连接 四,Listen() 监听请求连接 和 Accept() 接收连接请求 五,Receive() 与 Send() 六,释放资源 七,IPAddress 和 IPEndPoint
0 0
Socket 基本原理 | 学习笔记
快速学习 Socket 基本原理
0 0
Win Socket编程原理及简单实例
[转]http://www.cnblogs.com/tornadomeet/archive/2012/04/11/2442140.html  使用Linux Socket做了小型的分布式,如Linux C Socket编程原理及简单实例。
985 0
【读书笔记】socket函数
socket函数 简介 应用程序调用socket函数来创建一个能够进行网络通信的套接字。 1 2 3 4 5 /* 头文件 */ #include #include /* 函数原型 */ int socket(int domain, int...
493 0
Delphi-IOCP学习笔记<四>===小结<IOCP的简单例子>
今天把前几天研究的代码都整理了下。 我觉得刚开始学习IOCP,看简单的例子更容易入门。 先截取运行图   下面是这个是IOCP简单测试 点击运行服务,开启IOCP工作线程和监听过程。   创建客户端连接是使用的idtcpClient.
760 0
socket简单编程
server.c:从客户端读字符,然后将每个字符转换为大写并回送给客户端。 client.c:从命令行参数中获得一个字符串发给服务器,然后接收服务器返回的字符串并打印。   others... 1.该例子不仅功能简单,而且简单到几乎没有什么错误处理,我们知道,系统调用不能保证每次都成功,必须进行出错处理,这样一方面可以保证程序逻辑正常,另一方面可以迅速得到故障信息。 为使
791 0
python网络编程学习笔记(5):socket的一些补充
1、半开放socket利用shutdown()函数使socket双向数据传输变为单向数据传输。shutdown()需要一个单独的参数,该参数表示了如何关闭socket。具体为:0表示禁止将来读;1 表示禁止将来写;2表示禁止将来读和写。
598 0
+关注
杨粼波
网游的老兵
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载