Linux网络编程读书笔记(6)

第七章 UDP数据报

·7.1  UDP数据报

UDP源端口、UDP目的端口 标示进程;UDP数据报长度;校验和,可选。

UDP非面向连接,不可靠传输,具有较小传输时延。

 

·7.2  UDP传输过程

SERVER: socket() --> bind() --> recvfrom() --> sendto()-->close()

CLIENT : socket() --> sendto() --> recvfrom() --> close() 

服务器端和TCP协议相比少了listen()accept()两个过程,而客户端不需要建立连接

 

       头文件:<socket.h>

       发送和接收函数:

       int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);      //参数to是指定接收方地址

       int recvfrom(int sockfd, const void *buf, int len, unsigned int flags, const struct sockaddr *from, socklen_t *addrlen);   //参数from是保存发送方的地址

       int send(int sockfd, void *buf, int flags);      //使用connect绑定后,发送到缺省地址

       int recv(int sockfd, void *buf, int flags);      //使用connect绑定后,从缺省地址接收

    //socket(AF_INET, SOCK_DGRAM, 0)  创建一个UDP套接字

 

·7.3  UDP服务器和TCP服务器的比较

       使用UDP协议的服务器通常是非面向连接的,因此不用listenaccept的。UDP服务器只需要在其端口上等待客户机发来的数据报即可。

       TCP服务器需要和客户端进行连接然后,独占一个连接套接字为其服务;而UDP服务器实际并不和客户机进行连接,UDP服务器仅是接收报文,处理并返回结果。

       UDP协议并不关心数据报的可靠性和次序,而希望应用程序保证这些。

       TCP服务器中,服务器可以调用getsockpeer函数获取客户机地址信息和端口号,使用getsockname获取套接字对应的IP地址和端口号。

UDP服务器中,可以在recvfrom函数中获取数据报的源地址,使用getsockname获取数据报的端口。如果该UDP服务器有多个IP地址,则无法判断是哪个IP地址获取该数据报。因为UDP协议非面向连接,没有记录接收方的IP地址,此时如果需要明确知道是哪个IP地址收到该数据报,在服务器端需要为每个建立多个UDP套接字绑定在不同网络接口上,通过getsockname获取对应的IP号。

 

·7.4  UDP的“连接”

       UDP是非面向连接,但是也可以调用connect函数对套接字进行绑定到缺省IP地址上。

       UDP服务器调用conncet后,并不启用“三次握手”,仅仅记住目的地址和端口。在使用send函数时候会自动按照缺省情况来填写数据报头;同时也可以用sendto函数发送指定位置。

但在接收时候,如果套接字已绑定一个地址和端口,那么UDP服务器只接收该套接字上源地址和端口相同的数据报。如果一个数据报源地址和端口和该套接字设置不同,则丢弃它。而没有绑定地址和端口的UDP套接字可以接收任意来源的数据报。

可以多次调用connect函数修改UDP套接字的绑定地址和端口设置。如果调用connect(AF_UNSPEC, NULL, 0)可以取消对套接字的绑定。

 

·7.4 UDP应用程序性能改进

       1 解决报文的无序问题:

UDP报文设计一个数据序列号,接收到报文先进行排序后再转交给数据处理程序。

       2 解决报文的流量控制问题:

  如果客户端接收能力远高于服务器端发送速率,则会让网络传输性能大大下降;

如果客户端接收能力远低于服务器端发送速率,则会让UDP报文大量丢失,消耗服务器端资源。因此需要匹配双方的发送和接收速率,有利用提高整体性能。我们需要在应用程序中建立一种端对端的流量控制反馈机制,由客户端给服务器端发送接收能力的反馈,让服务器端动态调整发送速率。


 

第八章  域名系统和通用套接字选项

·8.1 域名系统

#include <netdb.h>

struct hostent *gethostbyname(const char *hostname); //指定域名地址来获取IP地址

struct hostent *gethostbyaddr(const char *addr, size_t len, int family); //指定IP地址获取域名

struct hostent{

       char *h_name;              //主机名

       char **h_alias;       //主机别名列表

       int h_addrtype;       //主机地址类型

       int h_length;           //主机地址长度

       char **h_addr_list;//主机IP地址列表

};

 

int gethostname(char *name, size_t len);  //返回本机域名地址 <unistd.h>

int uname(struct utsname *name);  //同上,#Include <sys/utsname.h>

struct servent *getservbyname(const char *servname, const char *protoname);//服务名获取端口

struct servent *getservbyport(int port, const char *protoname);  //由端口名获取服务信息

 

·8.2 套接字选项

#include <sys/socket.h>

int getsockopt(int sockfd, int level, int optname, void *potval, socklen_t *optlen);

int setsockopt(int sockfd, int level, int optname, cosnt void *potval, socklen_t *optlen);

[通用套接字选项,参考手册,略。]

 

 

第八章  域名系统和通用套接字选项

·8.1 域名系统

#include <netdb.h>

struct hostent *gethostbyname(const char *hostname); //指定域名地址来获取IP地址

struct hostent *gethostbyaddr(const char *addr, size_t len, int family); //指定IP地址获取域名

struct hostent{

       char *h_name;              //主机名

       char **h_alias;       //主机别名列表

       int h_addrtype;       //主机地址类型

       int h_length;           //主机地址长度

       char **h_addr_list;//主机IP地址列表

};

 

int gethostname(char *name, size_t len);  //返回本机域名地址 <unistd.h>

int uname(struct utsname *name);  //同上,#Include <sys/utsname.h>

struct servent *getservbyname(const char *servname, const char *protoname);//服务名获取端口

struct servent *getservbyport(int port, const char *protoname);  //由端口名获取服务信息

 

·8.2 套接字选项

#include <sys/socket.h>

int getsockopt(int sockfd, int level, int optname, void *potval, socklen_t *optlen);

int setsockopt(int sockfd, int level, int optname, cosnt void *potval, socklen_t *optlen);

[通用套接字选项,参考手册,略。]

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值