锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 在线教育 / SOCKET网络通信开发公开课 / Networking and Sockets网络和Sockets
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

3.17 Sockets-Ports and Protocols 端口和协议


个人经验理解:前面讲到的DNS就是一种网络服务,这类服务提供客户端需要的一类数据,占用网络主机上一个端口,也使用一种指定的协议,DNS服务就是使用了DNS协议。自己写的程序不能强占标准服务使用的端口,否则程序运行会不正常。
要点

  • 服务端口信息
  • 协议信息

3.17.1 服务端口信息

  • 多个进程在给定时间里可能使用给定的传输协议(通常指UDP或TCP)。为了区分不同的同时存在的服务,端口号必须是唯一性地指定。
  • 一个端口号只是个16位的整数;在socket地址结构体里,已经看到sin_port就是个端口号,端口号总是以网络顺序存储。
  • 端口号没有物理端脚这样的对应理解。端口号这个概念让人们能绘制些机械模拟图,表示出数据的流线关系,这样让程序理解方便些,总之,它只是个socket。
  • 特殊的服务占用特殊的端口号,这是国际标准。请看http://www.iana.org/assignments/port-numbers
  • 0-1023是经常用的端口。ftp使用了21,http使用了80。
  • 经常用的端口是保留的,也就是说,只有超级用户进程才能指定这些端口到socket里。这有助于阻止无赖服务器取巧代替一个服务。然而,非超级用户轻松具备连接这些端口的能力。
  • 端口号1024到65535之间为临时端口,动态端口和私有端口。IANA对这段没有规定。
  • 客户端使用临时端口。客户端不关心它实际用什么端口,只要它不重复就可以。这些端口使用管理是由相关的传输协议实现,这些协议关心指定和释放这些动态对象。
  • 端口指定的当前列表由文件/etc/services维护。下面打开这个文件看一下:

注意:

    • 对于给定服务,UDP和TCP传输协议指定的端口是一样的。这是官方策略和通用的,除了少量由历史原因不一致情况。
    • 尽管一些服务只使用了特殊的协议,端口对2个协议被委派一致。
    • 显示的有端口,但是并不代表端口代表的服务会在当前运行
  • 如果服务占用了端口,你的程序就不能再使用这个端口了。
  • 存取/etc/services文件的系统调用为:

#include <netdb.h>

struct servent  *getservbyname(const char *name,const char*proto);
struct servent  *getservbyport(int port,const char *proto);
struct servent  *getservent(void);
void  setservent(int stayopen);
void  endservent(void);
struct servent {
char *s_name;/*官方服务名称*/
char **s_aliases;/*别名列表*/
int s_port /*端口号*/
char *s_proto; /*使用协议*/
}
  • 示例

serv_entry=getservbyname(“ftp”,”tcp”);
返回描述了使用TCP协议的ftp服务对应的结构。
serv_entry=getservbyport(htons(80),”tcp”);
返回了描述使用TCP协议的HTTP服务对应的结构。

  • setservent()函数打开和翻阅/etc/services文件读取结果。如果stayopen=1,在下次调用获取函数前文件不会被关闭。
  • 一旦文件打开了,getservent()函数用来读取一行,处理结束用endservent()函数关闭文件。
  • 注意端口数字必须传递到这个函数里,以网络字节顺序保存到servent结构体里。

3.17.2 协议信息

  • 另外一个文件,/etc/protocols用他们里面的数字指定来连接不同的互联网协议,它的内容也由IANA维护。
  • 下面的函数用于扫描文件,函数也比较简单,有:

#include <netdb.h>

struct protoent  *getprotobyname(const char *name);
struct protoent  *getprotobynumber(int proto);
struct protoent  *getprotoent(void);
void  setprotoent(int stayopen);
void  endprotoent(void);
struct protoent  {
char *p_name;/*官方协议名称*/
char **p_aliases /*别名列表*/
int   p_proto;/*/协议数字*/
}
  • 函数用法简单,不再详述。

3.17.3.2 获取服务

  • 写个程序,带服务名和端口数字为参数,形式如下:

lab2 finger 80
(注意:服务和端口名称不需要一致)

  • 使用getservbyname()来检查端口名称是不是绑定到服务上了。对TCP和UDP都做检查。
  • 使用getservbyport()来检查服务是不是绑定到端口上。对TCP和UDP都做检查。
  • 在2种情况下,打印出服务名称的任何别名。

3.17.3.3获取所有服务

  • 写个程序,遍历出所有服务,并显示出服务占用的端口数字,可能的协议,别名。
友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州市金水区郑州大学北校区院(文化路97号院)内