栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Linux&C语言简单实现TCP同主机通信-网络编程

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux&C语言简单实现TCP同主机通信-网络编程

这里写目录标题
  • TCP客户端和服务器通信
    • 流程
    • 字节序转换函数
    • IP地址转换的函数:
    • 将套接字和网络信息结构体绑定bind
    • 代码实现
      • 01server.c
      • 02client.c
      • 执行结果
  • 6. 非原创

TCP客户端和服务器通信
  • 基于C语言实现,TCP练习——用read-write
流程
  1. 服务器:
    1.创建流式套接字 socket
    2.填充服务器的网络信息结构体
    3.将网络信息结构体和套接字进行绑定 bind
    4.将套接字设置成被动监听状态 listen
    5.阻塞等待客户端连接 accept
    6.收发数据 read/write
    7.关闭套接字 close

  2. 客户端:
    1.创建流式套接字 socket
    2.填充服务器的网络信息结构体
    3.与服务器建立连接 connect
    4.收发数据 read/write
    5.关闭套接字 close

字节序转换函数
  1. 主机字节序到网络字节序

h host 主机
n net 网络

将无符号4字节整型  从主机-->网络
uint32_t htonl(uint32_t hostlong);
将无符号2字节整型  从主机-->网络 
 uint16_t htons(uint16_t hostshort);
  1. 网络字节序到主机字节序
将无符号4字节整型  从网络-->主机 
uint32_t ntohl(uint32_t netlong);
将无符号2字节整型  网络-->主机 
uint16_t ntohs(uint16_t netshort);
IP地址转换的函数:
  1. inet_addr()
将strptr所指的字符串转换成32位的网络字节序二进制值。
in_addr_t inet_addr(const char*strptr);
  1. inet_ntoa()
将32位网络字节序二进制地址转换成点分十进制的字符串。
 char *inet_ntoa(stuct in_addr inaddr);
将套接字和网络信息结构体绑定bind
  1. 网络信息结构体 sockaddr
struct sockaddr {
	sa_family_t sa_family;
	char        sa_data[14];
}
只用于强制类型转换,防止编译器警告
  1. sockaddr_in / in_addr
struct sockaddr_in {
	sa_family_t    sin_family; 		
	in_port_t      sin_port;   		
	struct in_addr sin_addr;  		 		
 }; 		
struct in_addr {
	uint32_t       s_addr;    		
};
代码实现 01server.c
#include 


#include 
#include 

#include 

#include 
#include 
#include 

#include 

#include 
#include 
#include 

#include 

#include 
int main(int argc, char const *argv[])
{
    // 1.创建流式套接字
    // socket返回的文件描述符
    int sockfd = 0; // IPV4使用,//TCP
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        perror("socket error");
        exit(-1);
    }

    // 2.填充服务器的网络信息结构体
    struct sockaddr_in addr;
    //清空、填充0
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET; // IPV4
    //端口号  //将无符号2字节整型  主机-->网络
    addr.sin_port = htons(8888);
    // ip地址 //将strptr所指的字符串转换成32位的网络字节序二进制值。
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    //结构体长度
    socklen_t addr_len = sizeof(addr);

    // 3.将网络信息结构体和套接字进行绑定 bind
                      //强制类型转换
    if (bind(sockfd, (struct sockaddr *)&addr, addr_len) == -1)
    {
        perror("connect error");
        exit(-1);
    }

    // 4.将套接字设置成被动监听状态 listen
    if (-1 == listen(sockfd, 5))
    {
        perror("listen error");
        exit(-1);
    }

    // 5.阻塞等待客户端连接 accept
    //返回一个新的文件描述符,专门用于和该客户端通信
    int accept_fd = 0;
    printf("等待客户端n");
    if ((accept_fd=accept(sockfd, NULL, NULL))==-1)
    {
        perror("accept error");
        exit(-1);
    }
    printf("客户端连接成功n");
    while (1)
    {
        char buf[128] = {0};
        //收
        printf("客户端 >  ");
        fflush(stdout);
	    read(accept_fd, buf, 128);
	    //printf("客户端 >  %sn", buf);
        printf("%sn", buf);
        //将"996"(包括'')追加到buf后面,会覆盖buf的''
        //strcat(buf, "996");
        if (strcmp(buf,"quit")==0)
        {
            //关闭文件描述符
            close(sockfd);
            close(accept_fd);
            break;
        }
    
        //发
        printf("input  > ");
        memset(buf, 0, sizeof(buf));
        scanf("%s", buf);
        write(accept_fd, buf, 128);
        if (strcmp(buf,"quit")==0)//break;
        {
            //关闭文件描述符
            close(sockfd);
            close(accept_fd);
            break;
        }
    }
    
    

    //关闭文件描述符
    close(sockfd);
    close(accept_fd);
	
    return 0;
}

02client.c
#include 


#include 
#include 

#include 

#include 
#include 
#include 

#include 

#include 
#include 
#include 

#include 

#include 

int main(int argc, char const *argv[])
{
    // 1.创建流式套接字
    // socket返回的文件描述符
    int sockfd = 0; // IPV4使用,//TCP
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        perror("socket error");
        exit(-1);
    }

    // 2.填充服务器的网络信息结构体
    struct sockaddr_in addr;
    //清空、填充0
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET; // IPV4
    //端口号  //将无符号2字节整型  主机-->网络
    addr.sin_port = htons(8888);
    // ip地址 //将strptr所指的字符串转换成32位的网络字节序二进制值。
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    //结构体长度
    socklen_t addr_len = sizeof(addr);

    //3.与服务器建立连接 connect
                              //强制类型转换
    if(-1 == connect(sockfd, (struct sockaddr *)&addr, addr_len)){
		perror("connect error");
		exit(-1);
	}
    while (1)
    {
        char bu[128] = {0};
        //发
        printf("input  > ");
        scanf("%s", bu);
        write(sockfd, bu, 128);
        if (strcmp(bu,"quit")==0)//break;
        {
            //关闭文件描述符
            close(sockfd);
            break;
        }

        //收
        memset(bu, 0, sizeof(bu));
        printf("服务器 > ");
        fflush(stdout);
	    read(sockfd, bu, 128);
	    //printf("服务器  >  %sn", bu);
        printf("%sn", bu);
        if (strcmp(bu,"quit")==0)//break;
        {
            //关闭文件描述符
            close(sockfd);
            break;
        }
    
    }
    
   
    //关闭文件描述符
    close(sockfd);
   
    return 0;
}
执行结果

6. 非原创
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/879734.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号