【Linux C | 网络编程】入门知识:TCP协议、TCP客户端、TCP服务端

博客主页:https://blog.csdn.net/wkd_007
博客内容:嵌入式开发、Linux、C语言、C++、数据结构、音视频
本文内容:介绍网络编程入门知识:TCP协议、TCP客户端、TCP服务端
金句分享:你不能选择最好的,但最好的会来选择你——泰戈尔

本文未经允许,不得转发!!!

目录

  • 一、TCP协议概述
  • 二、一个最简单的TCP客户端
    • ✨2.1 tcp客户端步骤和代码
    • ✨2.2 tcp客户端相关函数
  • 三、一个最简单的TCP服务端
    • ✨2.1 tcp服务端步骤和代码
    • ✨2.2 tcp服务端相关函数
  • 四、总结


在这里插入图片描述

一、TCP协议概述

TCP协议的全称是传输控制协议(Transmission Control Protocol)。TCP是一个面向连接的协议,为用户进程提供可靠的全双工字节流。TCP套接字是一种流套接字( streamsocket)。TCP关心确认、超时和重传之类的细节。大多数因特网应用程序使用TCP。注意,TCP既可以使用IPv4,也可以使用IPv6。


TCP协议的几个特点:

  • 1、TCP是通过连接(connection)来通信的。TCP客户端与某个TCP服务端建立连接,然后通过这个连接与服务端交互数据,最后终止这个连接。
  • 2、TCP是可靠性(reliability)。当TCP向另一端发送数据时,它要求对端返回一个确认。如果没有收到确认,TCP就自动重传数据并等待更长时间。在数次重传失败后,TCP才放弃,如此在尝试发送数据上所花的总时间一般为4~10分钟(依赖于具体实现)。
    TCP会给每个分节关联一个序列号,如果接收到重复数据,可以判定数据重复并丢弃。
  • 3、TCP提供流量控制(flow control)。TCP总是会告诉对端,它一次能够从对端接收多少个字节的数据,这成为通告窗口(advertised window)。该窗口指出接收缓冲区的当前可用字节。
  • 4、TCP是全双工的(full-duplex)。表示在同一个TCP连接上,同一时刻可以同时发送、接收数据。

在这里插入图片描述

二、一个最简单的TCP客户端

✨2.1 tcp客户端步骤和代码

编写TCP客户端的步骤:

  • 1、创建TCP套接字socket
  • 2、指定TCP服务端ip和端口,bzero、inet_pton
  • 3、建立与TCP服务端的连接,connect
  • 4、交互数据
  • 5、关闭套接字
#include 
#include 
#include 
#include 
#include 

int main()
{
	// 1、创建TCP套接字socket
	int sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd<0)
		perror("socket error" );
	
	// 2、准备服务端ip和端口
	struct sockaddr_in servaddr;
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons (10086);
	if (inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr) <= 0) // 设置本机IP为服务端IP
		perror("inet_pton error");
	
	// 3、连接 connect
	if (connect(sockfd,(struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
		perror("connect error" );
	
	// 4、交换数据
	printf("TcpCli sockfd=%d, send msg\n",sockfd);
	write(sockfd, "Hello,I am tcp client", strlen("Hello,I am tcp client"));
	
	char recvline[256];
	int n = 0;
	while ( (n = read (sockfd, recvline, sizeof(recvline))) > 0)
	{
		recvline[n] = 0 ;/*null terminate */
		printf("recv[%s]\n",recvline);
	}
	
	if (n < 0)
		perror("read error" );
	
	// 5、关闭
	close(sockfd);

	return 0;
}

✨2.2 tcp客户端相关函数

  • socket 函数

    #include           /* See NOTES */
    #include 
    int socket(int domain, int type, int protocol);
    

    socket函数创建一个套接字描述符。man手册描述,socket创建一个通信端点并返回一个描述符。

    • 参数domain指定通信域,使用了AF_INET,表示是IPv4 Internet protocols协议的。
    • 参数type指定套接字类型,使用``,表示TCP协议的套接字(提供有序、可靠、双向、基于连接的字节流。可以支持带外数据传输机制)。
    • 参数protocol指定了要与套接字一起使用的特定协议。通常,在给定的协议族中,只有一个协议支持特定的套接字类型,在这种情况下,协议可以指定为0。
  • connect 函数

    #include           /* See NOTES */
    #include 
    int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    

    connect 函数将文件描述符sockfd引用的套接字连接到addr指定的地址。addrlen参数指定addr的大小。addr中地址的格式由套接字sockfd的地址空间决定;

在这里插入图片描述

三、一个最简单的TCP服务端

✨2.1 tcp服务端步骤和代码

编写TCP服务端的步骤:

  • 1、创建TCP套接字socket
  • 2、准备服务端ip和端口;
  • 3、绑定,bind
  • 4、监听,listen
  • 5、接受客户端连接,accept
  • 6、与客户端进行数据交互
  • 7、关闭套接字
#include 
#include 
#include 
#include 
#include 

int main()
{
	// 1、创建TCP套接字socket
	int sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd<0)
		perror("socket error" );
	
	// 2、准备服务端ip和端口
	struct sockaddr_in servaddr;
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons (10086);
	servaddr.sin_addr.s_addr = INADDR_ANY; // 指定ip地址为 INADDR_ANY,这样要是服务器主机有多个网络接口,服务器进程就可以在任一网络接口上接受客户端的连接
	
	// 3、绑定 bind
	if (bind(sockfd,(struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
		perror("bind error" );
	
	// 4、监听 listen
	if(listen(sockfd, 10) != 0)
		perror("listen error");
	
	printf("TcpSer sockfd=%d, start listening\n",sockfd);
	char recvline[256];
	while(1)
	{
		// 5、接受客户端连接
		int connfd = accept(sockfd, NULL, NULL);
		
		// 6、与客户端交换数据
		int n = read(connfd, recvline, sizeof(recvline));
		if(n>0)
		{
			recvline[n] = 0 ;/*null terminate */
			printf("recv connfd=%d [%s]\n",connfd,recvline);
		}
		write(connfd, "Hello,I am tcp server", strlen("Hello,I am tcp server"));
		close(connfd);
	}
	
	// 7、关闭
	close(sockfd);

	return 0;
}

socketbindlisten这3个调用步骤是任何TCP服务器准备所谓的监听描述符(listening descriptor)的正常步骤。


✨2.2 tcp服务端相关函数

tcp服务端相关函数有:socket、bind、listen、accept。socket函数可以参照上面 2.2 小节。

  • bind 函数
    #include           /* See NOTES */
    #include 
    int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    
    bind函数将addr指定的地址分配给文件描述符sockfd引用的套接字。addrlen指定addr指向的地址结构的大小。
  • listen 函数
    #include           /* See NOTES */
    #include 
    int listen(int sockfd, int backlog);
    
    listen函数将sockfd引用的套接字标记为被动套接字,标记后,可以使用accept函数接受传入连接请求的套接字。
    • backlog参数定义了sockfd的挂起连接队列可能增长到的最大长度。如果连接请求在队列已满时到达,则客户端可能会接收到带有ECONNREFUSED指示的错误,或者,如果底层协议支持重传,则可以忽略该请求,以便稍后重新尝试连接成功。
  • accept 函数
    #include           /* See NOTES */
    #include 
    int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    
    accept函数用于基于连接的套接字类型(SOCK_STREAM、SOCK_SEQPACKET)。它提取侦听套接字的挂起连接队列中的第一个连接请求sockfd,创建一个新的连接套接字,并返回一个引用该套接字的新文件描述符。新创建的套接字未处于侦听状态。原始套接字sockfd不受此调用的影响。

在这里插入图片描述

四、总结

本文主要介绍Linux下网络编程的基础知识,先是简单介绍一下TCP协议,然后给出一个TCP客户端、TCP服务端最简单的例子,最后介绍创建TCP客户端、TCP服务端需要用到的函数。

在这里插入图片描述
如果文章有帮助的话,点赞、收藏⭐,支持一波,谢谢

你可能感兴趣的:(#,✨Linux,C语言,网络,linux,TCP客户端代码,TCP服务端代码,TCP协议)