C/S架构学习之基于TCP的本地通信(服务器)

  • 基于TCP的本地通信(服务器):
  • 创建流程:
  • 一、创建字节流式套接字(socket函数):
c 复制代码
	int sock_fd = socket(AF_LOCAL,SOCK_STREAM,0);
  • 二、创建服务器和客户机的本地网络信息结构体并填充服务器本地网络信息结构体 (struct sockaddr_un):
  • 本地网络信息结构体:
c 复制代码
	#include <sys/un.h>
	struct sockaddr_un {
	    sa_family_t sun_family;               //AF_LOCAL
	    char        sun_path[108];            //pathname
	};
c 复制代码
	//填充服务器和客户机网络信息结构体
    struct sockaddr_un serveraddr,clientaddr;
    socklen_t serveraddr_len = sizeof(serveraddr);
    socklen_t clientaddr_len = sizeof(clientaddr);

    memset(&serveraddr,0,serveraddr_len);
    memset(&clientaddr,0,clientaddr_len);

    serveraddr.sun_family = AF_LOCAL;
    strcpy(serveraddr.sun_path,"./tcpserver");
  • 三、绑定字节流式套接字(bind函数):、
c 复制代码
	bind(sock_fd,(struct sockaddr *)&serveraddr,serveraddr_len);
  • 四、设置套接字为被监听状态(listen函数):
c 复制代码
	listen(sock_fd,5);
  • 五、阻塞等待客户端连接(accept函数):
c 复制代码
	accept(sock_fd,(struct sockaddr *)&clientaddr,&clientaddr_len);
  • 六、服务器端收发数据(recv函数、send函数):
c 复制代码
			memset(buf,0,sizeof(buf));
            if(-1 == (nbytes = recv(accept_fd,buf,sizeof(buf),0)))
            {
                perror("recv error");
                exit(-1);
            }
            else if(0 == nbytes)
            {
                printf("客户端[%s]断开了连接\n",clientaddr.sun_path);
                break;
            }
            printf("客户端[%s]发来数据[%s]\n",clientaddr.sun_path,buf);

            //组装应答消息
            strcat(buf,"-------k");
            ret = send(accept_fd,buf,sizeof(buf),0);
            if(-1 == ret)
            {
                perror("send error");
                exit(-1);
            }
  • 七、关闭套接字(close函数):
c 复制代码
	close(accept_fd);
	close(sock_fd);
  • 示例代码:
c 复制代码
	#include <stdio.h>
	#include <string.h>
	#include <stdlib.h>
	
	#include <unistd.h>
	#include <sys/socket.h>
	#include <sys/types.h>
	
	#include <netinet/ip.h>
	#include <sys/un.h>
	
	#include <arpa/inet.h>
	#include <stdbool.h>
	
	int main(int argc, char const *argv[])
	{
	    
	    //创建套接字
	    int sock_fd = socket(AF_LOCAL,SOCK_STREAM,0);
	    if(-1 == sock_fd)
	    {
	        perror("socket error");
	        exit(-1);
	    }
	    //填充服务器和客户机网络信息结构体
	    struct sockaddr_un serveraddr,clientaddr;
	    socklen_t serveraddr_len = sizeof(serveraddr);
	    socklen_t clientaddr_len = sizeof(clientaddr);
	
	    memset(&serveraddr,0,serveraddr_len);
	    memset(&clientaddr,0,clientaddr_len);
	
	    serveraddr.sun_family = AF_LOCAL;
	    strcpy(serveraddr.sun_path,"./tcpserver");
	
	    //服务器绑定套接字
	    if(-1 == bind(sock_fd,(struct sockaddr *)&serveraddr,serveraddr_len))
	    {
	        perror("bind error");
	        exit(-1);
	    }
	
	    //设置监听状态
	    if(-1 == listen(sock_fd,5))
	    {
	        perror("listen error");
	        exit(-1);
	    }
	
	    //阻塞等待客户端连接
	    int accept_fd = 0;
	    char buf[128] = {0};
	    int nbytes = 0;
	    int ret = 0;
	
	    //提示信息
	    printf("本地通信之TCP服务器启动!!!\n");
	    while(true)
	    {   
	        accept_fd = accept(sock_fd,(struct sockaddr *)&clientaddr,&clientaddr_len);
	        if(-1 == accept_fd)
	        {
	            perror("accept error");
	            exit(-1);
	        }
	        //收发数据
	        while(true)
	        {
	            memset(buf,0,sizeof(buf));
	            if(-1 == (nbytes = recv(accept_fd,buf,sizeof(buf),0)))
	            {
	                perror("recv error");
	                exit(-1);
	            }
	            else if(0 == nbytes)
	            {
	                printf("客户端[%s]断开了连接\n",clientaddr.sun_path);
	                break;
	            }
	            printf("客户端[%s]发来数据[%s]\n",clientaddr.sun_path,buf);
	
	            //组装应答消息
	            strcat(buf,"-------k");
	            ret = send(accept_fd,buf,sizeof(buf),0);
	            if(-1 == ret)
	            {
	                perror("send error");
	                exit(-1);
	            }
	
	        }
	
	        close(accept_fd);
	
	    }
	
	    //关闭套接字
	    close(sock_fd);
	
	    
	    return 0;
	}
  • 运行结果:
c 复制代码
	本地通信之TCP服务器启动!!!
	客户端[./tcpclient]发来数据[hello]
	客户端[./tcpclient]发来数据[hi]
	客户端[./tcpclient]发来数据[I Love China!!!]
  • 特别注意:
  • strcpy(serveraddr.sun_path,"./tcpserver");中tcpserver文件是套接字文件;
  • 如下所示:
c 复制代码
	srwxrwxr-x 1 linux linux     0 11月 10 05:58 tcpserver
相关推荐
EasyGBS9 小时前
摄像头还在线,画面已经不能用了?国标GB28181视频平台EasyGBS视频质量诊断怎么用
服务器·安全·音视频
程序员-Benothing10 小时前
Vim编辑器从入门到精通:模式、快捷键、配置、插件
linux·运维·服务器
wdfk_prog10 小时前
LWIP教程 09:从 `tcp_slowtmr()` 到 Fast Retransmit——TCP 超时重传与重复 ACK
服务器·网络·数据库·网络协议·tcp/ip
‎ദ്ദിᵔ.˛.ᵔ₎10 小时前
linux 进程信号 (上)
linux·服务器
Zooproxy全球IP代理10 小时前
住宅IP在AI行业中的技术应用:数据采集基础设施的工程实践
人工智能·网络协议·tcp/ip
辣知10 小时前
辣知·化智77 三千年接力写就的一本书
学习
小白学大数据10 小时前
拼多多反爬对抗实战:Scrapy 中间件化采集架构解析
开发语言·scrapy·中间件·架构
15Moonlight10 小时前
Linux网络(02):Socket 编程 UDP
linux·网络·udp
一木 之林10 小时前
Dify学习笔记 01 · 平台入门与实战:部署、五类应用、RAG与MCP(第1-16集)
人工智能·笔记·学习·计算机视觉