您现在的位置是:首页 >技术杂谈 >TCP网络编程网站首页技术杂谈

TCP网络编程

F.LASH. 2024-07-11 06:01:02
简介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等网络编程的相关接口,对我们后续的学习是非常有帮助的;
最后,各位小伙伴们如果喜欢我的分享可以点赞收藏哦,你们的认可是我创作的动力,一起加油!

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。