2-23TCP网络程序设计

    xiaoxiao2022-06-23  25

    (本节笔记的实验代码,在这里)

    1.  TCP编程模型函数化

            1.1  server端函数

                    创建socket——>socket();                 绑定地址   ——>bind();                 监听端口   ——>listen();                 等待连接   ——>accept();                 接收数据   ——>recv();                 发送数据   ——>send();                 结束连接   ——>close();         1.2  client端函数                 创建socket——> socket();                 连接服务器 ——>connect();                 接收数据   ——>recv();                 发送数据   ——>send();                 结束连接   ——>close(); 2.  函数学习     2.1创建套接字         函数名:                 socket         函数原型: man socket                 int socket(int domain, int type, int protocol);         函数功能:                 创建网络套接字。         所属头文件:                 <sys/types.h>         <sys/socket.h>         返回值:                 成功 :返回int类型的sockfd         失败 :返回-1         参数说明                 domain :AF_INET(IPV4因特网域)                                    AF_INET6(IPV6因特网域)。                 type :SOCK_DGRAM(固定长度的无连接的不可靠的报文传输)                              SOCK_RAW(IP协议的数据报接口,在POSIX.1中为可选)                              SOCK_SEQPACKET(固定长度的有序的可靠的面向连接的报文传输) SOCK_STREAM(有序的可靠的双向的面向连接的字节流)。                 protocol :通常是0。     2.2  绑定地址         函数名:                 bind         函数原型: man 2 bind                 int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);         函数功能:                 将套接字与地址关联。         所属头文件:                 <sys/types.h>         <sys/socket.h>         返回值:                 成功 :返回0         失败 :返回-1         参数说明                 sockfd :需要绑定的套接字ID。                 *addr :一个struct sockaddr结构的指针,里面存有server端地址。                         //一般用法为(struct sockaddr *)(&struct sockaddr_in)                 addrlen :地址长度。                 /***********************************************************                 struct sockaddr{    //该结构是通用的地质类型,包括IPv4和IP6                         sa_family_t sa_family;   //协议族                         char sa_data[14];            //地址                 }                 struct sockaddr_in{   //该结构是IPv4专用地址结构                         short int sin_family;          //协议族,AF_INET                         unsigned short int sin_port;   //端口号,2字节                         struct in_addr sin_addr;       //IPv4地址,4字节                         unsigned char sin_zero[8];   //用0填充8字节                    }                 struct in_addr{                         unsigned long s_addr;      //一个长整形的地址数据,                  }                                                      //需要把字符串转发为整形                 ***********************************************************                 in_addr_t inet_addr(const char *cp);                 <sys/socket.h> <netinet.in.h> <arpa/inet.h>                 功能:把字符串形式的IP地址转化为整形的IP地址(网络字节序)。                 范例:in_addr.s_addr = inet_addr ("192.168.0.1")                 char *inet_ntoa(struct in_addr);                 功能:把整形的IP地址转化为字符型的IP地址。                 ***********************************************************                 网络字节序:                         网络上通讯过程中,需把发送到网络上的数据转化为网络字节序(大端模式数据),接收数据时,要把数据转化为主机字节序。                 <arpa/inet.h>                 uint32_t htonl(uint32_t hostlong);                 功能:将32位数据从主机字节序转化为网络字节序                 范例:in_addr.s_addr = htonl(INADDR_ANY);                 uint16_t htons(uint16_t hostshort);                 功能:将16位数据从主机字节序转化为网络字节序                 uint32_t ntohl(uint32_t netlong);                 功能:将32位数据从网络字节序转化为主机字节序                 uint16_t ntohs(uint16_t netshort);                 功能:将16位数据从网络字节序转化为主机字节序                 ***********************************************************/     2.3  设置监听端口个数         函数名:                 listen         函数原型: man listen                 int listen(int sockfd, int backlog);         函数功能:                 设置监听端口个数,表示服务器愿意接受连接请求。         所属头文件:                 <sys/types.h>         <sys/socket.h>         返回值:                 成功 :返回0         失败 :返回-1         参数说明                 sockfd :server端套接字ID。

                    backlog :server端愿意接受连接的个数。

        2.4  等待连接         函数名:                 accept         函数原型: man 2 accept                 int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);         函数功能:                 等待连接请求,接受并建立连接。若无连接请求则进入阻塞。         所属头文件:                 <sys/types.h>         <sys/socket.h>         返回值:                 成功 :返回新的sockfd         失败 :返回-1         参数说明                 sockfd :server端的套接字ID。                 *addr :一个struct sockaddr结构的指针,里面存有client端地址。                         //一般用法为(struct sockaddr *)(&struct sockaddr_in)                 *addrlen :client端地址长度(变量)的地址。     2.5  接收数据         函数名: recv         函数原型: man recv                 ssize_t recv(int sockfd, void *buf, size_t len, int flags);         函数功能:                 控制如何接收数据。         所属头文件:                 <sys/types.h>         <sys/socket.h>         返回值:                 成功 :返回接收数据的大小         失败 :返回-1         参数说明                 sockfd :accept函数返回的新的sockfd。                 *buf :接收的数据存放的地址。                 len :接收的数据大小。                 flags :标志位,如果不需要设置可以直接设为0。     2.6发送数据         函数名:                 send         函数原型: man send                 ssize_t send(int sockfd, const void *buf, size_t len, int flags);         函数功能:                 控制如何发送数据。         所属头文件:                 <sys/types.h> <sys/socket.h>         返回值:                 成功 :返回发送数据的大小 失败 :返回-1         参数说明:                 sockfd :accept函数返回的新的sockfd。。                 *buf :需要发送的数据存放地址。                 len :发送数据的大小。                 flags :标志位,如果不需要设置可以直接设为0。     2.7  关闭连接         函数名:                 close         函数原型: man close

                    int close(int fd);

            函数功能:                 关闭连接。         所属头文件:                 <unistd.h>         返回值:                 成功 :返回0         失败 :返回-1         参数说明                 fd :sockfd。     2.8  连接服务器         函数名:                 connect         函数原型: man                  int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);         函数功能:                 client端向server端请求建立连接。         所属头文件:                 <sys/types.h>         <sys/socket.h>         返回值:                 成功 :返回0         失败 :返回-1         参数说明                 sockfd :client端sockid。                 *addr :一个struct sockaddr结构的指针,里面存有server端地址。                          //一般用法为(struct sockaddr *)(&struct sockaddr_in)                 addrlen :client端地址长度。 3.  综合实例 /*  touch server.c  */

    /* 利用TCP协议进行网络通讯的服务器端程序 */

    #include <stdio.h> #include <sys/socket.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #define PORTNUM 3333 int main() { int sockfd; int app_sockfd; int recv_sz; long addr_len; char buff[128]; struct sockaddr_in server_addr; struct sockaddr_in client_addr; /* 1.创建socket */ if(-1 == (sockfd = socket(AF_INET, SOCK_STREAM, 0))) { printf("create socket error!\n"); exit(1); } /* 2.绑定地址 */ bzero(&server_addr, sizeof(struct sockaddr_in)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORTNUM); server_addr.sin_addr.s_addr = htonl(INADDR_ANY); bind(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)); /* 3.监听端口 */ listen(sockfd, 5); while(1) { addr_len = sizeof(struct sockaddr); /* 4.等待连接 */ app_sockfd = accept(sockfd, (struct sockaddr *)(&client_addr), (socklen_t *)(&addr_len)); printf("server get connection from:%s\n", inet_ntoa(client_addr.sin_addr)); /* 5.接收数据 */ recv_sz = recv(app_sockfd, buff, 128, 0); buffer[recv_sz] = '\0'; printf("server received %s\n", buff); /* 6.结束连接 */ close(app_sockfd); } /* 7.结束连接 */ close(sockfd); return 0; }                                                                    /*  touch client.c  */

    /* 利用TCP协议进行网络通讯的客户端程序 */

    #include <stdio.h> #include <sys/socket.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #define PORTNUM 3333 int main() { int sockfd; int send_sz; char buff[128]; struct sockaddr_in server_addr; /* 1.创建socket */ if(-1 == (sockfd = socket(AF_INET, SOCK_STREAM, 0))) { printf("create socket error!\n"); exit(1); } /* 2.连接服务器 */ bzero(&server_addr, sizeof(struct sockaddr_in)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORTNUM); server_addr.sin_addr.s_addr = inet_addr("192.168.123.4"); if(-1 == connect(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)) { printf("connet fail!\n"); exit(1); } /* 4.发送数据 */ printf("Please input something:\n"); fgets(buff, 128, stdin); send(sockfd, buffe, strlen(buffer), 0); /* 5.结束连接 */ close(sockfd); return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-1123423.html

    最新回复(0)