【TCP回声服务器】一篇文章帮助你看懂TCP!

1、TCP回声服务器的概念

1.1 什么是TCP?

  TCP 的全称为传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

1.2 什么是回声服务器?

  回声服务器是指一种收到客户端发送的消息后,将消息回传至客户端服务器,这种服务器代码简单,但功能健全,非常适合帮助初学者理解网络编程中TCP协议。

2、TCP回声服务器的编程模型

2.1 编程模型

服务器端 S 客户端 C
创建套接字socket 创建套接字socket
准备通信地址(服务器的地址) 准备通信地址(服务器的地址)
绑定套接字和通信地址 连接服务器端S
监听
等待连接
接收/发送数据 发送/接收数据
关闭套接字 关闭套接字

2.2 服务器端编程步骤

  //创建套接字

  //准备通信地址

  //绑定socket与通信地址

  //监听

  //等待连接(因为TCP是有连接的通信,所以相比UDP多一个等待连接的过程)

  //接收数据,将接收到的数据存入缓冲区

  //发送数据,将缓冲区的数据发送出去

扫描二维码关注公众号,回复: 11701615 查看本文章

  //关闭套接字

2.3 客户端编程步骤

  //初始化网络库

  //创建套接字

  //准备通信地址

  //连接

  //发送数据

  //接收数据

  //关闭套接字

3、代码实现

3.1 服务器端代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>

typedef struct sockaddr* SP;

int main(int argc,const char* argv[])
{
    
    
	// 创建socket
	int sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(0 > sockfd)
	{
    
    
		perror("socket");
		return EXIT_FAILURE;
	}

	// 准备地址
	struct sockaddr_in addr = {
    
    };
	addr.sin_family = AF_INET;
	addr.sin_port = htons();
	addr.sin_addr.s_addr = INADDR_ANY;
	socklen_t addrlen = sizeof(addr);

	// 绑定
	if(bind(sockfd,(SP)&addr,addrlen))
	{
    
    
		perror("bind");
		return EXIT_FAILURE;
	}

	// 监听
	if(listen(sockfd,5))
	{
    
    
		perror("listen");
		return EXIT_FAILURE;
	}

	// 等待连接
	int clifd = accept(sockfd,(SP)&addr,&addrlen);
	if(0 > clifd)
	{
    
    
		perror("accept");
		return EXIT_FAILURE;
	}

	char buf[4096] = {
    
    };
	size_t buf_size = sizeof(buf);

	for(;;)
	{
    
    
		// 接收/返回数据
		size_t ret_size = read(clifd,buf,sizeof(buf));
		if(0 == strcmp("quit",buf))
		{
    
    
			printf("通信结束!\n");
			break;
		}	
		if(0 == ret_size)
		{
    
    
			printf("连接断开!\n");
			break;
		}
		printf("recv:[%s] bits:%d\n",buf,ret_size);
		strcat(buf,":return");
		write(clifd,buf,strlen(buf)+1);
	}

	// 关闭socket
	close(clifd);
}

3.2 客户端代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>

int main(int argc, char const *argv[])
{
    
    
    // 初始化网络库
    WSADATA wsaData;
    if(WSAStartup(MAKEWORD(2,2),&wsaData))
    {
    
    
        perror("WSAStartup");
        return EXIT_FAILURE;
    }

    // 创建socket
    int clifd = socket(AF_INET,SOCK_STREAM,0);
    if(0 > clifd)
    {
    
    
        perror("socket");
        return EXIT_FAILURE;
    }

    // 准备通信地址(由服务端决定)
    struct sockaddr_in addr = {
    
    };
    addr.sin_family = AF_INET;
    addr.sin_port = htons(9876);
    addr.sin_addr.s_addr = inet_addr("47.97.229.46");

    // 连接
    if(connect(clifd,(struct sockaddr*)&addr,sizeof(addr)))
    {
    
    
        perror("connect");
        return EXIT_FAILURE;
    }

    char buf[4096] = {
    
    };
    size_t buf_size = sizeof(buf);

    for(;;)
    {
    
    
        printf(">>>");
        gets(buf);
        send(clifd,buf,strlen(buf),0);
        if(0 == strcmp("quit",buf))
        {
    
    
            printf("通信结束!\n");
            break;
        }
        size_t ret_size = recv(clifd,buf,buf_size,0);
        printf("recv:[%s],bits:%d",buf,ret_size);
    }

    // 关闭socket
    closesocket(clifd);
    return 0;
}

4、结尾

  本文主要展示了TCP回声服务器的基本概念,及代码的实现,旨在更好的帮助初学者理解TCP通信的规则及格式,代码较为简单,功能实现的也很简单,但相信通过阅读本文一定能对TCP模式的通信有一个更深的认识。

猜你喜欢

转载自blog.csdn.net/weixin_48994377/article/details/108575318