文章目录
- 前言
- 一、TCP简介---传输控制协议
- 1. 特点
- 2. 安全可靠
- 3. TCP通信流程
- 二、TCP函数接口
- 2.1 socket
- 2.2 bind
- 2.3 listen
- 2.4 connect
- 2.5 accept
- 2.6 recv
- 2.7 send
- 三、TCP通信实例
- 1. 功能介绍
- 2. 引入库
- 3. 发送端
- 4. 发送端
- 总结
前言
上期分享了UDP下的网络编程,相信大家对网络通信已经有了自己的一些认知,那么我们本期就进一步来看一下TCP下的网络编程,感受一下TCP和UDP的相同点和不同点,实践证明一切,让我们来看看吧!
一、TCP简介—传输控制协议
1. 特点
(1)实现复杂(2)资源开销大(3)安全、可靠
2. 安全可靠
(1)传输数据前使用三次握手建立连接(2)传输过程中有确认、应答机制(3)传输结束时使用四次挥手结束连接
3. TCP通信流程
TCP是面向连接的传输方式(有连接)UDP是无连接的发送端:(1)socket (2)connect (3)send(4)recv (5)close 接收端:(1)socket(2)bind (3)listen (4)accept (5)recv (6)send(7)close
二、TCP函数接口
2.1 socket
int socket(int domain, int type, int protocol);
功能:创建一个用来通信的套接字文件描述符
参数:domain:通信域 AF_INET IPv4协议type:SOCK_DGRAM 用户数据报套接字 UDP SOCK_STREAM 流式套接字 TCPSOCK_RAW 原始套接字 protocol:默认为0
返回值:成功返回新文件描述符失败返回-1
2.2 bind
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:将IP地址和套接字绑定
参数:sockfd:套接字文件描述符addr:IP地址空间首地址addrlen:IP地址长度
返回值:成功返回0失败返回-1
2.3 listen
int listen(int sockfd, int backlog);
功能:监听三次握手链接请求
参数:sockfd:套接字文件描述符backlog:最大允许等待尚未建立连接的请求个数
返回值:成功返回0 失败返回-1
2.4 connect
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能:向收端发送三次握手链接
参数:sockfd:套接字addr:目的地址 addrlen:目的地址长度
返回值:成功返回0 失败返回-1 有阻塞功能: 如果接收方三次握手连接完成不了,则会导致connect阻塞
2.5 accept
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:接收三次握手链接请求,并建立一个新套接字
参数:sockfd:套接字addr:存放发送方IP地址空间首地址addrlen:IP地址长度
返回值:成功返回新文件描述符失败返回-1
2.6 recv
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
功能:接收数据
参数:sockfd:文件描述符buf:存放接收数据空间首地址len:最大接收数据的长度flags:属性默认为0
返回值:失败返回-1 成功返回实际接收字节数返回0 对方断开连接
2.7 send
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
功能:发送数据
参数:sockfd:套接字文件描述符buf:发送数据空间首地址 len:发送数据长度 flags:属性 默认为0
返回值:成功返回实际发送字节数失败返回-1
三、TCP通信实例
1. 功能介绍
(1)发送端发送hello world给接收端
(2)接收端进行接收并打印收到的消息
2. 引入库
头文件如下:
#ifndef __HEAD_H__
#define __HEAD_H__#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#endif
3. 发送端
发送端首先创建sockfd套接字,进而对ip地址进行请求访问,发送hello world的消息,代码如下:
#include "head.h"int main(int argc, const char *argv[])
{int sockfd = 0;struct sockaddr_in sendsddr;int ret = 0;char tmpbuff[1024] = {0};ssize_t nsize = 0;sockfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == sockfd){perror("fail to sockfd");return -1;}sendsddr.sin_family = AF_INET;sendsddr.sin_port = htons(50000);sendsddr.sin_addr.s_addr = inet_addr("192.168.209.128");ret = connect(sockfd, (struct sockaddr *)&sendsddr, sizeof(sendsddr));if (-1 == ret){perror("fail to connect");return -1;}sprintf(tmpbuff, "hello world!");nsize = send(sockfd, tmpbuff, strlen(tmpbuff), 0);if (-1 == nsize){perror("fail to send");return -1;}return 0;
}
4. 发送端
接收端接受来自于发送端的消息并进行打印,代码如下:
#include "head.h"int main(int argc, const char *argv[])
{ int sockfd = 0;struct sockaddr_in recvaddr;int confd = 0;int ret = 0;char tmpbuff[1024] = {0};ssize_t nsize = 0;sockfd = socket(AF_INET, SOCK_STREAM, 0);if (-1 == sockfd){perror("fail to sockfd");return -1;}recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(50000);recvaddr.sin_addr.s_addr = inet_addr("192.168.209.129");ret = bind(sockfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));if (-1 == ret){perror("fail to bind");return -1;}ret = listen(sockfd, 10);if (-1 == ret){perror("fail to listen");return -1;}confd = accept(sockfd, NULL, NULL);if (-1 == confd){perror("fail to accept");return -1;}nsize = recv(confd, tmpbuff, sizeof(tmpbuff), 0);if (nsize <= 0){perror("fail to recv");return -1;}printf("recv:%s\n", tmpbuff);return 0;
}
这个就是使用tcp进行单向通信的一个简单例子,各位小伙伴可以来练练手,看下对TCP的掌握如何,如果可以还可以编写双向通信实例;
总结
本期主要分享的是TCP网络编程的相关函数接口以及具体实现的方法,希望大家一定得掌握socket,bind,accept,connect,send,recv等网络编程的相关接口,对我们后续的学习是非常有帮助的;
最后,各位小伙伴们如果喜欢我的分享可以点赞收藏哦,你们的认可是我创作的动力,一起加油!