美文网首页
TCP基本套接字编程笔记(一)套接字函数

TCP基本套接字编程笔记(一)套接字函数

作者: pangdong | 来源:发表于2017-11-01 22:03 被阅读0次

    使用TCP套接字编程可以实现基于TCP/IP协议的面向连接的通信,它分为服务端(Server)和客户端(Client)两个部分,具体流程图如下所示:


    流程图.png

    现在就基本套接字函数做学习笔记:

    socket()函数

    为了执行I/O,无论是服务端还是客户端,首先必须调用socket()函数,产生TCP套接字,作为TCP通信的传输端点。

    #include <sys/socket.h>
    int socket(int family,int type,int protocol);
    

    该函数调用成功,则返回一个小的非负的整数值,失败则返回-1;

    family参数指明协议族,它的值常用为:

    family=AF_INET;//IPv4协议;
    family=AF_INET6;//IPv6协议;
    family=AF_ROUTE;//路由套接口。
    

    type参数指明产生套接字的类型,它的值常用为:

    type=SOCK_STREAM;//字节流套接口,TCP常用的形式;
    type=SOCK_DGRAM;//数据报套接口,UDP常用的形式 ;
    type=SOCK_RAW;//原始套接口
    

    protocol参数是协议标志,一般在调用socket()函数时将其设置为0。(但如果是原始套接字,就需要为其指定一个常值)

    //eg:调用socket()函数 
    #include <sys/socket.h>
    ...
    int sockfd;
    //crteate socket
    if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
    {
           //handle exception
           ...
    }
    

    bind()函数

    绑定函数的作用就是为调用socket()函数产生的套接字分配一个本地协议地址,建立地址与套接字的对于关系。

    #include <sys/socket.h>
    int bind(int sockfd,const struct sockaddr *server,socklen_len addrlen);
    

    该函数调用成功返回0,若出错则返回-1,并置错误号errno;

    sockfd参数是套接字函数返回的套接字描述符;

    server参数是指向特定于协议的地址结构的指针,指定用于通信的本地协议地址;

    addrlen参数是指定该套接字地址结构的长度;

    //eg: 调用bind()函数
    #include <sys/socket.h>
    ...
    int sockfd;
    int port = 1234;//bind 的端口号是1234
    struct sockaddr_in server;
    ...
    //对服务器的地址结构初始化赋值,IP地址是一个通配地址,由内核选择。
    bzero(&server,sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(port);
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    //调用bind()函数将描述符sockfd与server套接字地址结构中的协议地址绑定 
    if(bind(sockfd,(struct sockaddr *)&server,sizeof(server)) == -1)
    {
           //handle exception
           //如果调用失败,则进行异常处理
           ...
    }
    ...
    

    listen()函数

    监听函数的作用就是将未连接的套接字转换成被动套接字,使它处在监听模式下,指示内核应接受发向该套接字的连接请求。

    #include <sys/socket.h>
    int listen(int sockfd,int backlog);
    

    该函数调用成功返回0,若出错则返回-1,并置errno值;

    sockfd参数是要设置的描述符;

    backlog参数规定了请求队列中的最大连接数;

    //eg:调用listen()函数
    #include <sys/socket.h>
    ...
    int sockfd;
    int BACKLOG = 5;//设置监听的最大连接数为5
    ...
    //调用listen()函数,将sockfd描述符设置为监听描述符
    if(listen(sockfd,BACKLOG) == -1)
    {
           //handle exception
           //如果调用失败,则进行异常处理
           ...
    }  
    ...
    

    accept()函数

    接受函数的作用就是使服务器接受客户端的连接请求。

    #include <sys/socket.h>
    int accept(int listenfd,struct sokaddr *client,socklen_t *addrlen);
    

    该函数调用成功后,返回三个值:

    (1):accept()函数的返回值,已连接套接字描述符;
    (2):client参数参会客户端的协议地址,包括IP地址和端口号等; 
    (3):addrlen参数返回客户端地址结构的大小。
    

    如果调用失败则返回-1,并置errno值。

    listenfd参数是由sockfd()函数产生的套接字描述符,在调用accept()函数前,已经调用listen()函数将此套接字变成了监听套接字;

    client参数是用来返回连接对方的套接字地址结构;

    addrlen参数是用来返回连接对方的套接字的结构长度。

    //eg:调用accept()函数
    #include <sys/socket.h>
    ...
    int listenfd,connfd;//定义两个套接字描述符,监听套接字描述符和已连接套接字描述符
    struct sockaddr_in client;
    socklen_t addrlen;
    addrlen=sizeof(client);//得到client当前的长度
    ...
    //调用accept()函数,接收连接请求,返回已连接套接字描述符
    connfd = accept(listenfd,(struct sockaddr *)&client,&addrlen);
    if(connfd == -1)
    {
           //handle exception
           //如果调用失败,则进行异常处理
           ...
    }
    ...
    

    connect()函数

    连接函数的作用就是让TCP客户端使用来配置套接字,建立一个与TCP服务器的连接。(激发TCP的三次握手过程)

    #include <sys/socket.h>
    int connect(int sockfd,const struct sockaddr *addr,socklen_t addrlen);
    

    该函数调用成功后返回0,若出错则返回-1;

    sockfd参数是有sockd()函数返回的套接字描述符;

    addr参数是指向服务器的套接字地址结构的指针;

    addrlen参数是该套接字地址结构的大小

    //eg:调用connect()函数
    #include <sys/socket.h>
    ...
    int sockfd;
    struct sockaddr_in server;
    ...
    bzero(&server,sizeof(server));//为套接字地址结构server设置初始值0
    //位套接字地址结构中的成员复制,客户端要建立链接的服务器IP地址为127.0.0.1,端口号为1234.
    server.sin_family = AF_INET;
    server.sin_port = htons(1234);
    server.sin_addr.s.addr = inet_addr("127.0.0.1");
    //调用connect()函数与服务器建立连接
    if(connect(sockfd,(struct sockaddr *)&server,sizeof(server)) ==
    -1)
    {
           //handle exception
           //如果调用失败,则进行异常处理
           ...
    }
    ...
    

    数据传输函数:write()和read()函数

    当服务器和客户端的连接建立起来后,就可以进行双向的数据传输了。

    write()和read()函数

    write()函数用于数据的发送:

    #include <unistd.h>
    int write(int sockfd,char *buf,int len);
    

    该函数调用成功返回大于0的整数,也就是发送的字节数,若出错则返回-1;

    buf参数是指向一个用于发送信息的数据缓冲区;

    len参数是指明传送数据缓冲区的大小。

    read()函数用于数据的接收

    #include <unistd.h>
    int read(int sockfd,char *buf,int len);
    

    该函数调用成功返回大于0的整数,也就是发送的字节数,若出错则返回-1;

    buf参数是指向一个用于接收信息的数据缓冲区;

    len参数是指明接收数据缓冲区的大小。

    //eg:调用read()函数
    #include <unistd.h>
    #include <sys/sockfd.h>
    #define MAXDATASIZE 100;//定义接收信息的数据缓冲区的长度 
    ...
    int num,connfd;
    char buf[MAXDATASIZE];
    ...
    //接收数据,整数num返回接收的字节数
    if(((num = read(connfd,buf,MAXDATASIZE)) > 0))
    {
           //handle data
           //处理接收到的数据
           ...
    }
    ...
    

    close()函数

    关闭函数的作用就是关闭套接字,并立即返回到进程。

    #include <unistd.h>
    int close(int sockfd);
    

    下一章开始介绍基本TCP套接字编程实例。

    相关文章

      网友评论

          本文标题:TCP基本套接字编程笔记(一)套接字函数

          本文链接:https://www.haomeiwen.com/subject/vxlnpxtx.html