【网络编程】详解UDP/TCP套接字的创建流程-LMLPHP


 目录

一、网络编程套接字

1、一些概念

1.1源IP地址和目的IP地址

1.2端口号port

1.3TCP和UDP的性质

1.4网络字节序、IP地址类型转换、数据接收与发送函数、popen函数

2、UDP套接字

2.1UDP服务器创建流程

2.2UDP客户端创建流程

2.3创建socket套接字

2.4绑定套接字对应的IP地址、端口号

2.5客户端、服务器数据的接收与发送

3、TCP套接字

3.1TCP服务器创建流程

3.2TCP客户端创建流程

3.3创建socket套接字

3.4绑定套接字对应的IP地址、端口号

3.5服务器设置socket为监听状态

3.6服务器获取客户端连接请求

3.7客户端发起连接请求


UDP/TCP客户端、服务器代码可参考本人gitee

一、网络编程套接字

1、一些概念

1.1源IP地址和目的IP地址

源IP地址:发送主机的IP地址。

目的IP地址:接收主机的IP地址。

1.2端口号port

端口号是传输层的协议的内容。

        既然网络通信的双方本质都是进程,为什么不直接使用pid来标定网络通信双方通信进程的唯一性,而是使用端口号呢?1、解耦2、例如客户端需要找到服务器进程,因为进程每次创建销毁pid是会变的,而网络编程弄了个端口号,直接写死了是哪个进程,这样每次都能找到。

        那么怎么找呢?操作系统内部维护了一张哈希表,key是端口号,value是进程PCB的地址。

1.3TCP和UDP的性质

UDP:

TCP:

1.4网络字节序、IP地址类型转换、数据接收与发送函数、popen函数

可以使用以下库函数做网络字节序和主机字节序的转换:

BYTEORDER(3)
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

例如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。

可以使用以下库函数对ip地址进行转换:

INET(3) 
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int inet_aton(const char *cp, struct in_addr *inp);
in_addr_t inet_addr(const char *cp);//将字符串转uint32_t的同时转为网络字节序
in_addr_t inet_network(const char *cp);
char *inet_ntoa(struct in_addr in);//将32位IPv4地址(in_addr结构体)转换成点分十进制字符串形式的IP地址
struct in_addr inet_makeaddr(int net, int host);
in_addr_t inet_lnaof(struct in_addr in);
in_addr_t inet_netof(struct in_addr in);

popen函数==pipe+fork+exec*

POPEN(3)    
#include <stdio.h>
FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);

2、UDP套接字

UDP套接字种类及接口

2.1UDP服务器创建流程

2.2UDP客户端创建流程

相关指令及函数:

ifconfig 显示网络设备信息,找到127.0.0.1本地回环地址
ps axj | grep udpServer过滤出当前的udpServer进程
netstat -nuap//n:能显示数字的现实成数字;u:udp;a:all;p:进程
sudo netstat -nuap//n:以数字形式显示地址和端口号,不进行反向解析,a:all,u::udp,p:process ID/name,
sudo netstat -altp//l::listen,t:tcp
recvfrom
sendto
close
bzero

2.3创建socket套接字

SOCKET(2)      
#include <sys/types.h> 
#include <sys/socket.h>
int socket(int domain, int type, int protocol);

2.4绑定套接字对应的IP地址、端口号

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

【网络编程】详解UDP/TCP套接字的创建流程-LMLPHP

2.5客户端、服务器数据的接收与发送

UDP 套接字是无连接协议,必须使用recvfrom函数接收数据,sendto函数发送数据:

RECV(2)
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
SEND(2)      
#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
          	const struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);

3、TCP套接字

3.1TCP服务器创建流程

3.2TCP客户端创建流程

3.3创建socket套接字

同UDP创建套接字的方法,只不过在传参时UDP传入SOCK_DGRAM(数据报),而TCP传入SOCK_STREAM(字节流)

_sockfd=socket(AF_INET,SOCK_DGRAM,0);//UDP网络通信+数据报
_listenfd=socket(AF_INET,SOCK_STREAM,0);//TCP网络通信+字节流

3.4绑定套接字对应的IP地址、端口号

同UDP。

3.5服务器设置socket为监听状态

因为TCP是有连接的协议,需要使用listen函数将一个套接字设置为监听状态。

LISTEN(2)   
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);

3.6服务器获取客户端连接请求

ACCEPT(2) 
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

3.7客户端发起连接请求

CONNECT(2)   
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
05-18 12:32