unix网络编程中一些常见的函数的总结

一些unix网络编程中常见的函数总结:

(1)socket()函数:该函数是TCP套接口的特色名字,该函数返回一个小整数描述字,在以后的其他函数调用中,我们就用它来表示这个套接口)

用于生成socket描述符(soketDescrīptor)

声明:SOCKETsocketint af,int type,intprotocol;

参数:第一个参数表示:协议族和地址族,一下三个常用的协议族:

PF_UNIX:unix系统内部协议

PE_INET:ip版本4

PE_INET6:ip版本6

第二个参数:通信类型,相关的常数如下:

SOCK_STREAM:以字节流形式通信

SOCK_DGRAM:数据以独立的数据包形式进行流动

SOCK_RAW:是低于传输层的低级协议或吴立成使用的

第三个参数:protocol-所使用的协议(通常指定为0)

返回值:当函数成功调用时返回一个新的SOCKET(SocketDescrīptor),而当失败时返回INVALID_SOCKET或者是-1. 


(2)connect()函数:(主要是用于客户端用于给服务器端建立tcp链接调用该函数将触发tcp的三次握手过程)

定义函数:int  connect (int sockfd,struct sockaddr * serv_addr,int addrlen);connect函数通常用于客户端建立tcp连接。

参数:

sockfd:唯一标识一个套接字(上面socket函数产生的套接口描述符)。

serv_addr(sockaddr_in的对象):套接字s想要连接的主机地址和端口号(即相应的服务器的主机地址和服务器的端口号)。

addrlenname缓冲区的长度。

返回值:

成功则返回0,失败返回-1,错误原因存于errno中。 


(3)bind()函数:(主要是将套接字和地址信息相互关联,建立地址与套接字的对应关系

描述:在套接口中,一个套接字只是用户程序与内核交互信息的枢纽,它自身没有太多的信息,也没有网络协议地址和端口号等信息,在进行网络通信的时候,必须把一个套接字与一个地址相关联,这个过程就是地址绑定的过程。许多时候内核会我们自动绑定一个地址,然而有时用户可能需要自己来完成这个绑定的过程,以满足实际应用的需要,最典型的情况是一个服务器进程需要绑定一个众所周知的地址或端口以等待客户来连接。这个事由bind的函数完成。

原型:#include<sys/socket.h>

intbind(int sockfd, struct sockaddr* addr, socklen_t addrlen)

返回:0──成功,-1──失败

参数描述:

参数sockfd

指定地址与哪个套接字绑定,这是一个由之前的socket函数调用返回的套接字。调用bind的函数之后,该套接字与一个相应的地址关联,发送到这个地址的数据可以通过这个套接字来读取与使用。

参数addr

指定地址。这是一个地址结构,并且是一个已经经过填写的有效的地址结构。调用bind之后这个地址与参数sockfd指定的套接字关联,从而实现上面所说的效果。

参数addrlen

正如大多数socket接口一样,内核不关心地址结构,当它复制或传递地址给驱动的时候,它依据这个值来确定需要复制多少数据。这已经成为socket接口中最常见的参数之一了。

备注:bind函数并不是总是需要调用的,只有用户进程想与一个具体的地址或端口相关联的时候才需要调用这个函数。在一般的情况下,对于服务器进程问题需要调用bind函数,对于客户进程则不需要调用bind函数。 

(4)listen()函数:(主要用于服务器端

listen函数使用主动连接套接口(是一个将调用connect发起链接的客户端套接口)变为被连接套接口,使得一个进程可以接受其它进程的请求,从而成为一个服务器进程。在TCP服务器编程中listen函数把进程变为一个服务器,并指定相应的套接字变为被动连接。

listen函数在一般在调用bind之后-调用accept之前调用,它的函数原型是:

#include<sys/socket.h>

intlisten(int sockfd, int backlog)

返回:0──成功,-1──失败

参数sockfd

listen函数作用的套接字,sockfd之前由socket函数返回。在被socket函数返回的套接字fd之时,它是一个主动连接的套接字,也就是此时系统假设用户会对这个套接字调用connect函数,期待它主动与其它进程连接,然后在服务器编程中,用户希望这个套接字可以接受外来的连接请求,也就是被动等待用户来连接。由于系统默认时认为一个套接字是主动连接的,所以需要通过某种方式来告诉系统,用户进程通过系统调用listen来完成这件事。

参数backlog

这个参数涉及到一些网络的细节。在进程正理一个一个连接请求的时候,可能还存在其它的连接请求。因为TCP连接是一个过程,所以可能存在一种半连接的状态,有时由于同时尝试连接的用户过多,使得服务器进程无法快速地完成连接请求。如果这个情况出现了,服务器进程希望内核如何处理呢?内核会在自己的进程空间里维护一个队列以跟踪这些完成的连接但服务器进程还没有接手处理或正在进行的连接,这样的一个队列内核不可能让其任意大,所以必须有一个大小的上限。这个backlog告诉内核使用这个数值作为上限。

毫无疑问,服务器进程不能随便指定一个数值,内核有一个许可的范围。这个范围是实现相关的。很难有某种统一,一般这个值会小30以内。

当调用listen之后,服务器进程就可以调用accept来接受一个外来的请求。

(5)accept()函数:(建立一个与客户端的链接

对于服务器编程中最重要的一步等待并接受客户的连接,那么这一步在编程中如何完成,accept函数就是完成这一步的。它从内核中取出已经建立的客户连接,然后把这个已经建立的连接返回给用户程序,此时用户程序就可以与自己的客户进行点到点的通信了。

accept函数等待并接受客户请求:

#include<sys/socket.h>

intaccept(int sockfd, struct sockaddr* addr(用来接收客户端的地址信息等), socklen_t* len)

返回:非负描述字——成功,-1——失败

accept默认会阻塞进程,直到有一个客户连接建立后返回,它返回的是一个新可用的套接字,这个套接字是连接套接字。此时我们需要区分两种套接字,一种套接字正如accept的参数sockfd,它是监听套接字,在调用listen函数之后,一个套接字会从主动连接的套接字变身为一个监听套接字;而accept返回是一个连接套接字,它代表着一个网络已经存在的点点连接。自然要问的是:为什么要有两种套接字?原因很简单,如果使用一个描述字的话,那么它的功能太多,使得使用很不直观,同时在内核确实产生了一个这样的新的描述字。

参数sockfd

参数sockfd就是上面解释中的监听套接字,这个套接字用来监听一个端口,当有一个客户与服务器连接时,它使用这个一个端口号,而此时这个端口号正与这个套接字关联。当然客户不知道套接字这些细节,它只知道一个地址和一个端口号。

参数addr(用来存放提出请求的客户端的信息:诸如地址结构等信息,通过accept之后客户端的诸如ip地址和端口之类的信息就存放在了这个参数中。)

这是一个结果参数,它用来接受一个返回值,这返回值指定客户端的地址,当然这个地址是通过某个地址结构来描述的,用户应该知道这一个什么样的地址结构。如果对客户的地址不感兴趣,那么可以把这个值设置为NULL

参数len

如同大家所认为的,它也是结果的参数,用来接受上述addr的结构的大小的,它指明addr结构所占有的字节个数。同样的,它也可以被设置为NULL

如果accept成功返回,则服务器与客户已经正确建立连接了,此时服务器通过accept返回的套接字来完成与客户的通信。 


(6)字节排序函数:uint16_t htons(uint16_thost16bitvalue

                                  uint32_t htons(uint32_thost16bitvalue

            以上的两个主要是主机的字节序值转换成网络字节序值

                                  uint16_t ntohs(uint16_thost16bitvalue)

                                  uint32_t ntohs(uint32_thost16bitvalue)

            以上的两个函数主要是将网络字节序值装换成主机的字节序值

(7)字节操作函数:

  void  bzero(void *dest,size_t nbytes)将相应的结构体置0

  void  bcopy(const void *src,void *dest,size_nbytes)

  int     bcmp(const void *ptr1,const void *ptr2,size_t nbytes)


(8)、linux的system()函数(用来执行shell命令的函数)system(执行shell 命令)

相关函数fork,execve,waitpid,popen
表头文件#i nclude<stdlib.h>
定义函数
        int system(const char * string);
函数说明
        system()会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命>令执行完后随即返回原调用的进程。在调用system()期间SIGCHLD 信号会被暂时搁置,SIGINT和SIGQUIT 信号则会被忽略。
返回值
=-1:出现错误 
=0:调用成功但是没有出现子进程 
>0:成功退出的子进程的id
        如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-1。若参数string为空指针(NULL),则返回非零值>。
如果system()调用成功则最后会返回执行shell命令后的返回值,但是此返回值也有可能为 system()调用/bin/sh失败所返回的127,因此最好能再检查errno 来确认执行成功。
附加说明
        在编写具有SUID/SGID权限的程序时请勿使用system(),system()会继承环境变量,通过环境变量可能会造成系统安全的问题。
范例
        #i nclude<stdlib.h>
main()
{
system(“ls -al /etc/passwd /etc/shadow”);
}
执行结果:

-rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd
-r--------- 1 root root 572 Sep 2 15 :34 /etc/shado

例2:

char tmp[];
sprintf(tmp,"/bin/mount -t vfat %s /mnt/usb",dev);
system(tmp);
其中dev是/dev/sda1。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值