TCP/IP网络编程总结
基础连接篇
服务器端:socket()---->bind()---->listen()---->accept()---->read()/write()---->close()
客户端:socket()---->connect()---->read()/write()---->close()
-
函数说明
-
int socket(int domain, int type, int protocol)
创建套接字。成功时返回文件描述符,失败时返回**-1**。
- domain:套接字中使用的协议族(Protocol Family)信息。IPV4:PF_INET。
- type:套接字数据传输类型信息。面向连接的套接字:SOCK_STREAM。
- protocol:计算机 间通信中使用的协议信息。大部分使用相同的协议就为0。
例:sock = socket(PR_INET, SOCK_STREAM, 0);
-
int bind(int sockfd, struct sockaddr *myaddr, socklen_t addrlen)
向套接字分配网络地址。成功时返回0,失败时返回-1。
- sockfd:要分配地址信息(IP地址和端口号)的套接字文件描述符。
- myaddr:存有地址信息的结构体变量地址值。
- addrlen:第二个结构体变量的长度。
例:struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET(IPV4网络协议中使用的地址簇);
serv_addr.sin_addr.s_addr = htol(INADDR_ANY);(网络字节序,利用常数INADDR_ANY自动分配ip)
serv_addr.sin_port = htons(atoi(serv_port));(分配16位端口号,0~65535)
bind(serv_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
-
int listen(int sock, int backlog)
服务端进入等待连接请求状态。成功时返回0,失败时返回**-1**。
- sock:需要被监听的套接字。
- backlog:连接请求等待队列(Queue)的长度,若为5,最表示最多使5个连接请求进入队列。
-
int accept(int sock, struct sockaddr *addr, socklen_t *addlen)
服务端受理客户端连接请求。成功时返回创建的套接字文件描述符,失败时返回**-1**。
- sock:服务器套接字文件描述符。
- addr:保存发起连接请求的客户端地址信息的变量地址值,调用函数后向传递来的地址变量参数填 充客户端地址信息。
- addrlen:addr结构体的长度,调用函数后,改变量即被填入客户端地址长度。
-
int connect(int sock, struct sockaddr *servaddr, socklen_t addrlen)
客户端发起请求连接。成功时返回0,失败时返回**-1**。
- sock:客户端套接字文件描述符。
- servaddr:保存目标服务器端地址信息的变量地址。
- addrlen:以字节为单位传递已传递给第二个结构体参数servaddr的地址变量长度。
-
ssize_t write(int fd, const void *buf, size_t nbytes)
将数据写入文件。成功时返回写入的字节数,失败时返回**-1**。
- fd:显示数据传输对线的文件描述符。
- buf:保存要传输数据的缓冲地址值。
- nbytes:要传输数据的字节数。
-
ssize_t read(int fd, void *buf, size_t nbytes)
读取文件中的数据。成功时返回接受的字节数,失败时返回**-1**,若TCP另一端连接被关闭,返回0。
- fd:显示数据传输对线的文件描述符。
- buf:保存要传输数据的缓冲地址值。
- nbytes:要传输数据的字节数。
-
多线程篇
-
线程创建及运行
-
int pthread_create(pthread_t * restrict thread, const pthread_attr_t * restrict attr, void *(* start_routine)(void *), void * restrict arg)
创建线程,成功时返回0,失败时返回其他值。
- restrict关键字:告诉编译器,对象已经被指针所引用,不能通过除该指针外的所有其他直接或间接方式修改对象内容。
- thread:保存新创建线程ID的变量地址值(内存单元)。
- attr:用于传递线程属性的参数,传递NULL时,创建默认属性的线程。
- start_routine:相当于线程main函数的、在单独执行流中执行的函数地址值(函数指针)。
- arg:通过第三个参数传递调用函数时包含传递参数信息的变量地址值。
例:pthread_create(&t_id, NULL, thread_main, (void*)&thread_param)
-
int pthread_join(pthread_t thread, void ** status)
使线程进入等待状态,直到第一个参数为ID的线程终止为止,并引导线程销毁。成功时返回0,失败时返回其他值。
子线程合入主线程,主线程阻塞等待子线程结束,然后回收子线程资源。
- thread:该参数值ID的线程终止后才会从该函数返回。
- status:保存线程的main函数返回值的指针变量地址值。也就是有些线程的main函数有返回值,返回值的指针的地址保存在这里。
-
int pthread_detach(pthread_t thread)
调用引导线程销毁。成功时返回0,失败时返回其他值。
主线程与子线程分离,子线程结束后,资源自动回收。
- thread:终止的同时需要销毁的线程ID。
-
-
线程同步互斥量
-
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
int pthread_ mutex_destroy(pthread_mutex_t *mutex)
互斥量的创建及销毁。成功时返回0,失败时返回其他值。
- mutex:创建互斥量时传递保存呼出量的变量地址值,销毁时传递需要销毁的互斥量地址值。
- attr:传递即将创建的互斥量属性,没有特别指定的属性时传递NULL。
-
int pthread_mutex_lock(pthread_mutex_t *mutex)
int pthread_mutex_unlock(pthread_miutex_t *mutex)
利用互斥量锁住或者释放临界区。成功时返回0,失败时返回其他值。
-
-
线程同步信号量
-
int sem_init(sem_t *sem, int pshared, unsigned int value)
int sem_destroy(sem_t *sem)
信号量的创建及销毁。成功时返回0,失败时返回其他值。
- sem:创建信号量时传递保存信号量的变量地址值,销毁时传递需要销毁的信号量变量地址值。
- pshared:传递0时,创建只允许一个进程内部使用的信号量。传递其他值时,创建可由多个进程共享的信号量。
- value:指定新创建的信号量初始值。一般为0或1。
-
int sem_post(sem_t *sem)
int sem_wait(sem_t *sem)
- sem:传递保存信号量读取值的变量地址值,传递给sem_post时信号量增1,传递给sem_wait时信号量减1。
-
I/O复用篇
-
select
-
void FD_ZERO(fd_set *fdset)
将fdset清零使集合不含任何fd -
void FD_CLR(int fd, fd_set *fdset)
将fd从fdset中删除 -
void FD_SET(int fd, fd_set *fdset)
将fd加入fdset集合 -
int FD_ISSET(int fd, fd_set *fdset)
检测fd是否在fdset集合中,可以在select返回后,用FD_ISSET进行测试,找出需要注意的描述符 -
int select(int maxfd, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timeval *timeout)
设置检查(监视)范围及超时。成功时返回大于0的值,失败时返回**-1**。当select返回时,描述符集合将被修改以指示哪些描述符正处于可读、可写或有错误的状态。- maxfd:监视对象文件描述符数量。
- readset:将所有关注“是否存在待读取数据”的文件描述符注册到fd_set型变量,并传递其地址值。
- writeset:将所有关注“是否可传输无阻塞数据”的文件描述符注册到fd_set型变量,并传递其地址值。
- exceptset:将所有关注“是否发生异常”的文件描述符注册到fd_set型变量,并传递其地址值。
- timeout:调用select函数后,为防止陷入无线阻塞的状态,传递超时(time-out)信息。
-
-
epoll
-
int epoll_create(int size)
创建epoll。成功时返回epoll文件描述符,即epfd,失败时返回**-1**。
- size:epoll实例的大小。
-
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
在其内部注册监视对象文件描述符。成功时返回0,失败时返回-1。
- epfd:用于注册监视对象的epoll例程的文件描述符。
- op:用于指定监视对象的添加、删除或更改等操作。
- fd:需要注册的监视对象文件描述符。
- event:监视对象的事件类型。
例:epoll(A, EPOLL_CTL_ADD, B, C)
代表epoll例程A中注册文件描述符B,主要目的是监视参数C中的事件。
-
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
返回发生事件的文件描述符数,同时在第二个参数指向的缓冲中保存事件的文件描述符集合。
- epfd:表示事件发生监视范围的epoll例程的文件描述符。
- events:保存发生时间的文件描述符集合的结构体地址值。
- maxevents:第二个参数中可以保存的最大事件数。
- timeout:以1/1000秒为单位的等待时间,传递-1时,一直等待到事件发生。
-
-
多种I/O函数(send和recv函数提供了read和write函数一样的功能,不同的是他们提供了四个参数)。
-
ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags)
发送数据。成功时返回发送的字节数,失败时返回**-1**。
- sockfd:表示与数据传输对象的连接的套接字文件描述符。
- buf:保存待传输数据的缓冲地址值。
- nbytes:待传输的字节数。
- flags:传输数据时指定的可选项信息。
-
ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags)
接受数据。成功时返回发送的字节数(收到EOF时返回0),失败时返回**-1**。
- sockfd:表示与数据接收对象的连接的套接字文件描述符。
- buf:保存待传输数据的缓冲地址值。
- nbytes:待接收的字节数。
- flags:接收数据时指定的可选项信息。
-
可选项
可选项(option) 含义 send recv MSG_OOB 用于传输带外数据(Out-of-band data) √ √ MSG_PEAK 验证输入缓冲中是否存在接收数据 √ MSG_DONTROUTE 传输过程不按路由表,在本地寻找目的地 √ MSG_DONTWAIT 调用I/O函数时不阻塞,用于非阻塞I/O √ √ MSG_WAITALL 防止函数返回,直到接收全部请求的字节数 √
-
-
文件打开函数
-
int open(const char *path, int access, int mode)
打开文件。
- path:打开或创建的目标文件。
- access:打开方式。只读(O_RDONLY)、只写(O_WRONLY)、读写(O_RDWR)
- mode:对个参数选项。O_APPEND、O_CREATE等等。
-
FILE *fopen(char *filename, char *mode)
利用fopen转换为FILE结构体指针。成功时返回转换的FILE结构体指针,失败时返回NULL。
- filename:需要转换的文件描述符。
- mode:将要创建的FILE结构体指针的模式信息。(r:read;w:write;a:append;w+:read/write)
open fopen 属于低级I/O 属于高级I/O。 返回一个文件描述符 返回一个文件指针。 无缓冲。 有缓冲。 与read、write配合。 与fread、fwrite配合。
-