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;
    clientaddr.sun_family = AF_LOCAL;
    strcpy(serveraddr.sun_path, "./tcpserver");  //tcpserver是一个套接字类型的文件
    strcpy(clientaddr.sun_path, "./tcpclient"); //tcpclient是一个套接字类型的文件
  • 三、客户机绑定字节流式套接字(bind函数):
c 复制代码
	bind(sock_fd, (struct sockaddr *)&clientaddr, clientaddr_len);
  • 四、与服务器建立连接(connect函数):
c 复制代码
	connect(sock_fd, (struct sockaddr *)&serveraddr, serveraddr_len);
  • 五、客户机端发收数据(send函数、recv函数):
c 复制代码
		memset(buf, 0, sizeof(buf));
        fgets(buf,sizeof(buf),stdin);
        buf[strlen(buf) - 1] = '\0';
        //给服务器发送消息
        int ret1 = send(sock_fd,buf,sizeof(buf),0);
        if(-1 == ret1)
        {
            perror("send error");
            exit(-1);
        }

        memset(buf,0,sizeof(buf));
        //接收服务器的应答消息
        int ret2 = recv(sock_fd,buf,sizeof(buf),0);
        if(-1 == ret2)
        {
            perror("recv error");
            exit(-1);
        }

        printf("服务器的应答消息[%s]\n",buf);
  • 六、关闭套接字(close函数):
c 复制代码
	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;
	    clientaddr.sun_family = AF_LOCAL;
	    strcpy(serveraddr.sun_path, "./tcpserver");  //tcpserver是一个套接字类型的文件
	    strcpy(clientaddr.sun_path, "./tcpclient"); //tcpclient是一个套接字类型的文件
	
	    // 客户机绑定套接字
	    if (-1 == bind(sock_fd, (struct sockaddr *)&clientaddr, clientaddr_len))
	    {
	        perror("bind error");
	        exit(-1);
	    }
	
	    // 与服务器建立连接
	    if (-1 == connect(sock_fd, (struct sockaddr *)&serveraddr, serveraddr_len))
	    {
	        perror("connect error");
	        exit(-1);
	    }
	    char buf[128] = {0};
	    int ret1 = 0;
	    int ret2 = 0;
	    // 提示信息
	    printf("本地通信之TCP客户机成功连接服务器!!!\n");
	
	    // 收发数据
	    while (true)
	    {
	        memset(buf, 0, sizeof(buf));
	        fgets(buf,sizeof(buf),stdin);
	        buf[strlen(buf) - 1] = '\0';
	        //给服务器发送消息
	        int ret1 = send(sock_fd,buf,sizeof(buf),0);
	        if(-1 == ret1)
	        {
	            perror("send error");
	            exit(-1);
	        }
	
	        memset(buf,0,sizeof(buf));
	        //接收服务器的应答消息
	        int ret2 = recv(sock_fd,buf,sizeof(buf),0);
	        if(-1 == ret2)
	        {
	            perror("recv error");
	            exit(-1);
	        }
	
	        printf("服务器的应答消息[%s]\n",buf);
	        
	
	    }
	
	    // 关闭套接字
	    close(sock_fd);
	
	    return 0;
	}
  • 运行结果:
c 复制代码
	本地通信之TCP客户机成功连接服务器!!!
	hello
	服务器的应答消息[hello-------k]
	hi
	服务器的应答消息[hi-------k]
	I Love China!!!
	服务器的应答消息[I Love China!!!-------k]
相关推荐
小成C2 小时前
Vibe Coding 时代,研发体系该怎么重新分工
人工智能·架构·全栈
Assby4 小时前
从洋葱模型看Java与Go的设计哲学:为什么它们如此不同?
java·后端·架构
用户77312305407167 小时前
为什么选 Redis Stream 而不是 Kafka:任务队列选型实战
架构
badhope10 小时前
AI Skill 技术全景解析——从“聊天机器人”到“全能战神”的进化之路
架构·github
毛骗导演10 小时前
万字解析 OpenClaw 源码架构-代理系统(二)
前端·架构
im_AMBER10 小时前
从0到1实现块级编辑器的文件导入
前端·架构
毛骗导演10 小时前
万字解析 OpenClaw 源码架构-代理系统(一)
前端·架构
程序新视界12 小时前
OpenClaw真的那么神吗?技术架构解密
架构
架构师沉默1 天前
别又牛逼了!AI 写 Java 代码真的行吗?
java·后端·架构