您现在的位置是:首页 >技术杂谈 >TCP网络编程网站首页技术杂谈
TCP网络编程
简介TCP网络编程
文章目录
前言
上期分享了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 流式套接字 TCP
SOCK_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
", tmpbuff);
return 0;
}
这个就是使用tcp进行单向通信的一个简单例子,各位小伙伴可以来练练手,看下对TCP的掌握如何,如果可以还可以编写双向通信实例;
总结
本期主要分享的是TCP网络编程的相关函数接口以及具体实现的方法,希望大家一定得掌握socket,bind,accept,connect,send,recv等网络编程的相关接口,对我们后续的学习是非常有帮助的;
最后,各位小伙伴们如果喜欢我的分享可以点赞收藏哦,你们的认可是我创作的动力,一起加油!
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。