UNIX( linux) 网络编程

bzero( *arg, sizeof(arg) )将整个数据结构智位0, memset(*arg, 0, sizeof(arg) ),意义一样,但记忆更麻烦。

fputs是一个函数,具有的功能是向指定的文件写入一个字符串(不自动写入字符串结束标记符‘\0’)。成功写入一个字符串后,文件的位置指针会自动后移,函数返回值为非负整数;否则返回EOF(符号常量,其值为-1)。

int fputs(const char *str, FILE *stream);
返回值:该函数返回一个非负值,如果发生错误则返回 EOF(-1)。
(1)str:这是一个数组,包含了要写入的以空字符终止的字符序列。

(2)sstream:指向 FILE 对象的指针,该 FILE 对象标识了要被写入字符串的流

用函数,因为要有函数调用,增加了执行时的开销,效率不如宏,但是可代码重用。用宏虽然没有函数调用,但是因为在使用这个宏的地方,代码会被展开编译,增加了程序文件的大小。总起来说,参数和宏是一个用空间换时间还是用时间换空间的抉择。

getaddrinfo(), gethostbyname()。

端口划分(1023 known,1024-49151register 49152-65535dynamic



SYN标识建立连接        Synchronize
FIN表示响应
ACK表示响应    ACK (ACKnowledge Character) 
PSH表示有DATA数据传输

RST表示连接重置Reset

netdump



IPv6的 报文头部结构如图:
版本号表示协议版本.值为6
流量等级主要用于QoS
流标签用来标识同一个流里面的报文
载荷长度表明该IPv6包头部后包含的字节数,包含扩展头部
下一报头该字段用来指明报头后接的报文头部的类型,若存在扩展头,表示第一个扩展头的类型,否则表示其上层协议的类型,它是IPv6各种功能的核心实现方法
跳数限制该字段类似于IPv4中的TTL,每次转发跳数减一,该字段达到0时包将会被丢弃
源地址标识该报文的来源地址
目的地址标识该报文的目的地址

inet6 telnet ping


struct in_addr {

    in_addr_t a_addr;//32bit

}

struct sockaddr_in {

     uint8_t    sin_len;

    sa_family_t    sin_family;

    in_port_t        sin_port;

    struct   in_addr  sin_addr;

    char                sin_zero[8];

}

void func(主体, 约束, 客体, 约束);

结构体使用地址

通用套接字结构

struct sockaddr_in {

    uint8_t         sa_len;

    sa_family_t    sa_family;

     char                sa_data[14];

}

casting (struct sockaddr*)&xx.



从进程到内核传递套截至结构的函数有: bind, connect, sendto


从内核传到进程的有: accept, recvfrom, getsockname, getpeername,    

在网络编程中, 值-结果参数最常见的例子是所返回套接字地址结构的长度,


网络字节顺序是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


字节操纵函数://<strings.h>
源自4.3bsd套接字提供:
void bzero(void *s, size_t n);
void bcopy(const void *src, void *dest, size_t n);
int bcmp(const void *s1, const void *s2, size_t n);

源自ANSC C提供://<string.h>
void *memset(void *s, int c, size_t n);
void *memcpy(void *dest, const void *src, size_t n);

int memcmp(const void *s1, const void *s2, size_t n);


地址转换函数://<arpa/inet.h>

int inet_aton(const char *cp, struct in_addr *inp); /返回:有效为1,无效为0

in_addr_t inet_addr(const char *cp);//有效返回地址,否则INADDR_NONE(-1)

in_addr_t inet_network(const char *cp);//返回地址


新的函数,兼容v4和v6: int inet_pton(int family, const char* *strptr, void *addrptr)//返回:成功为1,无效为0, 出错-1

const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len)//返回:成功为结果的指针,出错为NULL #define NULL ((void*)0)


另外:AF_INET 为 2, AF_INET 为 10;

struct sockaddr_in6 addr6;  addr6.sin_addr6;

ssize_t  read(int fd, void* buf, size_t count); 

搜索
ssize_t readline(int fd, void *usrbuf, size_t maxlen),
ssize_t write(int fd, const void *buf, size_t count);

a) >0,表示成功读取的字节数,如果小于n,说明中间遇到了EOF;
b)==0 表示一开始读取就遇到EOF;
c) -1 表示错误(这里的errno绝对不是EINTR)。

int socket(int domain, int type, int protocol);//返回:成功返回一个小整数例如3,出错返回-1。socket()函数用于根据指定的地址族、数据类型和协议来分配一个套接口的描述字及其所用的资源。如果协议protocol未指定(等于0),则使用缺省的连接方式。

对于使用一给定地址族的某一特定套接口,只支持一种协议。但地址族可设为AF_UNSPEC(未指定),这样的话协议参数就要指定了。协议号特定于进行通讯的“通讯域”。


bind(int sockfd, int maxNums)//将一本地地址与一套接口捆绑。本函数适用于未连接的数据报或流类套接口,在connect()或listen()调用前使用。当用socket()创建套接口后,它便存在于一个名字空间(地址族)中,但并未赋名。bind()函数通过给一个未命名套接口分配一个本地名字来为套接口建立本地捆绑(主机地址/端口号)。

面向连接的网络应用程序分为客户端和服务器端。服务器端的执行流程一般为4步,客户端程序相对简单,一般需要两个步骤。

服务器端执行流程4步如下:
(1)调用socket函数,建立一个套接字,该套接字用于接下来的网络通信。
(2)调用bind函数,将该套接字绑定到一个地址,并制定一个端口号,
(3)调用listen函数,使用该套接字监听连接请求
(4)当请求来到时,调用accept函数复制该套接字处理请求
客户端执行流程2步如下:
(1)调用socket函数,创建一个套接字
(2)调用connect函数使用该套接字与服务器进行连接

listen

int connect(SOCKET s, const struct sockaddr * name, int namelen);//connect()用来将参数sockfd 的socket 连至参数serv_addr 指定的网络地址. 结构sockaddr请参考bind(). 参数addrlen 为sockaddr 的结构长度.返回值:成功则返回0, 失败返回-1, 错误原因存于errno 中.

 accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);//如果没有错误产生,则accept()返回一个描述所接受包的SOCKET类型的值。否则的话,返回INVALID_SOCKET错误,应用程序可通过调用WSAGetLastError()来获得特定的错误代码。

addrlen所指的整形数初始时包含addr所指地址空间的大小,在返回时它包含实际返回地址的字节长度。


setsockopt()#include <sys/socket.h>
int setsockopt(int s,int level,int optname,
const char *optval,int optlen);
s:标识一个套接字的描述符。
level:选项定义的层次;目前仅支持SOL_SOCKET和IPPROTO_TCP层次。
optname:需设置的选项。
optval:指针,指向存放选项值的缓冲区。
optlen:optval缓冲区长度。

send 有两种套接口的选项:一种是布尔型选项,允许或禁止一种特性;另一种是整形或结构选项。允许一个布尔型选项,则将optval指向非零整形数;禁止一个选项optval指向一个等于零的整形数。对于布尔型选项,optlen应等于sizeof(int);对其他选项,optval指向包含所需选项的整形数或结构,而optlen则为整形数或结构的长度。SO_LINGER选项用于控制下述情况的行动:套接口上有排队的待发送数据,且closesocket()调用已执行。参见closesocket()函数中关于SO_LINGER选项对closesocket()语义的影响。

recv



I/O模型

阻塞式IO

非阻塞     ssize_t recvfrom(int sockfd,void *buf,size_t len,unsigned int flags, struct sockaddr *from,socket_t *fromlen)


I/O复用(select,poll)


信号驱动




异步

5种 I/O 模型的比较



#include <sys/select.h>
int select( int nfds, fd_set FAR* readfds, fd_set * writefds, fd_set * exceptfds, const struct timeval * timeout);
nfds:是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,不能错!在Windows中这个参数的值无所谓,可以设置不正确。
readfds:(可选)指针,指向一组等待可读性检查的套接口。
writefds:(可选)指针,指向一组等待可写性检查的套接口。
exceptfds:(可选)指针,指向一组等待错误检查的套接口。

timeout:select()最多等待时间,对阻塞操作则为NULL。




#include <sys/epoll.h>
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。epoll除了提供select/poll那种IO事件的水平触发(Level Triggered)外,还提供了边缘触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,减少epoll_wait/epoll_pwait的调用,提高应用程序效率。


#include<unistd.h>  
#include<fcntl.h>  
int fcntl(int fd, int cmd);  
int fcntl(int fd, int cmd, long arg);  

int fcntl(int fd, int cmd ,struct flock* lock);  


关闭非阻塞式I/O:


[cpp] view plain copy
#include <stdio.h>  
#include <unistd.h>  
#include <fcntl.h>  
#include <errno.h>  
  
//取消非阻塞    
static void setblocking(int sockfd) {    
    int flag &= ~O_NONBLOCK;    
    if (fcntl(sockfd, F_SETFL, flag) < 0) {    
        perror("fcntl F_SETFL fail");    
    }    

}  


ioctl是设备驱动程序中对设备的I/O通道进行管理的函数 。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的调用个数如下: 
int ioctl(int fd, ind cmd, …); 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《UNIX/Linux编程实践教程》是一本非常实用的编程教材,对于学习和掌握UNIX/Linux编程的人来说,是一本不可或缺的参考书。 本书主要介绍了UNIXLinux系统下的编程基础知识、常用库函数以及实际应用技巧。首先,书中详细阐述了UNIXLinux的基本概念、文件系统、进程管理、输入输出等基础知识,为读者打下坚实的理论基础。然后,通过大量实例和案例,详细介绍了C语言在UNIXLinux环境下的编程技巧和常用函数的使用方法,例如文件操作、进程管理、网络编程等。同时,还介绍了常用的开发工具和调试技巧,使读者能够更加高效地进行编程实践。 《UNIX/Linux编程实践教程》使用简明易懂的语言,结合大量案例和实例进行讲解,使读者能够更好地理解和掌握所学知识。此外,书中还配有丰富的习题和实践项目,帮助读者巩固所学内容,并实际应用所学知识进行项目开发。 通过学习《UNIX/Linux编程实践教程》,读者能够系统地学习UNIXLinux系统下的编程知识,掌握基本的开发技巧和调试方法,并能够灵活应用于实际项目开发中。无论是初学者还是有一定编程基础的人,都可以通过这本教程提升自己的编程水平,并在UNIXLinux环境下进行高效的开发工作。 总之,《UNIX/Linux编程实践教程》具有理论与实践相结合、内容丰富全面的特点,是一本实用性很强的编程教材,值得每个想要学习UNIXLinux编程的人去阅读和学习。 ### 回答2: UNIX/Linux编程实践教程是一本非常经典且实用的电子书,该书的pdf版本提供了更方便的阅读和学习方式。本书包含了丰富的实例和案例,旨在帮助读者理解UNIX/Linux系统的编程原理和实践技巧。 该书的内容主要包括以下方面:首先介绍了UNIX/Linux系统的基础知识,包括文件系统、进程管理、网络编程等。接着深入讲解了Shell编程和系统调用的使用方法和技巧,帮助读者快速掌握UNIX/Linux系统的编程技术。 此外,该书还介绍了常用的开发工具和环境,如GCC编译器、Make工具等,以及如何使用它们进行程序的编译和调试。同时,还讲解了常见的UNIX/Linux应用开发技术,如网络编程、多线程编程等,使读者能够更好地开发和优化自己的应用程序。 这本书的特点是实用性强,结合了丰富的实例和案例,让读者能够更好地理解和掌握UNIX/Linux编程技术。此外,该书还提供了逐步指导和实践练习,帮助读者逐步提升自己的编程能力。 总的来说,UNIX/Linux编程实践教程是一本非常优秀的电子书,适合想要学习和深入了解UNIX/Linux系统的开发人员和爱好者。无论是初学者还是有一定经验的开发人员,都可以从中受益匪浅。如果你正在学习UNIX/Linux编程,我强烈推荐你阅读这本书的pdf版本。 ### 回答3: 《UNIX/Linux编程实践教程》是一本经典的计算机编程教程,对于学习UNIX/Linux操作系统编程的人来说是一本非常有价值的参考书。这本书主要介绍了UNIX/Linux环境下的开发工具和编程技术,包括Shell脚本编程、C语言编程、系统编程等内容。 《UNIX/Linux编程实践教程》的特点之一是它的全面性和实用性。书中详细讲解了UNIX/Linux环境下各种常用的开发工具和命令,如gcc、make、grep、sed等,以及如何使用它们进行编程和调试。此外,书中还介绍了常用的编程技巧和方法,如文件操作、进程管理、内存管理等,让读者能够更好地理解和掌握UNIX/Linux系统编程的要点。 这本书的另一个亮点是它的实践性。《UNIX/Linux编程实践教程》中包含了大量实例和案例,通过这些实例,读者可以直接动手实践并应用所学的知识。这种实践性的教学方法可以帮助读者更好地理解和记忆所学的内容,并增强对UNIX/Linux编程的实际应用能力。 总的来说,《UNIX/Linux编程实践教程》是一本非常实用的编程教程,它以通俗易懂的语言讲解了UNIX/Linux系统编程的基本原理和实践技巧,具有很高的实用性和可操作性。对于想要学习UNIX/Linux系统编程的人来说,这本书是一个非常好的选择,可以帮助他们快速入门并提高编程能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值