文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

tcp通信,客户端服务端

2023-09-09 15:49

关注

进行过程 

//TCP通信的流程

//服务器端(被动接受连接的角色)

创建一个用于监听的套接字

        -监听:监听有客户端的连接

        -套接字:这个套接字其实就是一个文件描述符

将这个监听文件描述符和本地的IP和端口绑定(IP和端口就是服务器的地址信息)

        -客户端连接服务器的时候使用的就是这个IP和端口

设置监听,监听的fd开始工作

阻塞等待,当有客户端发起连接,解除阻塞,接受客户端的连接,会得到一个和客户端通信的套接字(fd)

通信

        -接收数据

        -发送数据

通信结束,断开连接

//客户端

创建一个用于通信的套接字(fd)

连接服务器,需要指定连接的服务器和IP和端口

连接成功了,客户端可以直接和服务器端通信

             -接收数据

             -发送数据

通信结束,断开连接

 

字节序转换函数

发送端总是把要发送的数据转换成大端字节序数据后再发送,而接收端直到对方传送过来的数据总数采用大端字节序,所以接收端可以自身采用的字节序决定是否对接收到的数据进行转换(小端机转换,大端机不转换)

网络字节序采用大端

 

 

IP地址转化

 比如用点分十进制字符串表示 IPv4 地址,以及用 十六进制字符串表示 IPv6 地址。但编程中我们需要先把它们转化为整数(二进制数)方能使用。而记录 日志时则相反,我们要把整数表示的 IP 地址转化为可读的字符串

 

 

tcp/ip协议族

struct sockaddr_in  {    sa_family_t sin_family;         in_port_t sin_port;    struct in_addr sin_addr;        unsigned char sin_zero[sizeof (struct sockaddr) -   __SOCKADDR_COMMON_SIZE -   sizeof (in_port_t) -   sizeof (struct in_addr)];  };struct in_addr{    in_addr_t s_addr;};

 端口复用

 

 套接字函数

 

 

 show me the Code

客户端代码

#include #include #include #include #include using namespace std;int main() {    int fd = socket(AF_INET, SOCK_STREAM, 0);    if (fd == -1) {perror("socket"); return -1;}    struct sockaddr_in seaddr;    inet_pton(AF_INET, "127.0.0.1",&seaddr.sin_addr.s_addr);    seaddr.sin_family = AF_INET;    seaddr.sin_port = htons(9999);    int ret = connect(fd, (struct sockaddr*)&seaddr,sizeof(seaddr));        if (ret == -1) {perror("connect"); return -1;}    while(1) {        char sendBuf[1024] = {0};        fgets(sendBuf, sizeof(sendBuf), stdin);        write(fd, sendBuf, strlen(sendBuf) + 1);        //接收        int len = read(fd, sendBuf, sizeof(sendBuf));        if (len==-1) {            perror("read");            return -1;        }else if(len > 1) {            printf("read buf = %s\n", sendBuf);        }else {            printf("服务器已经断开连……\n");            break;        }    }    close(fd);    return 0;    return 0;}

服务端代码

#include #include #include #include #include #include int main() {    //创建socket    int lfd = socket(AF_INET, SOCK_STREAM, 0);    if (lfd == -1) {        perror("socket");        return -1;    }    struct sockaddr_in seraddr;    seraddr.sin_family = AF_INET;    seraddr.sin_addr.s_addr = INADDR_ANY;    seraddr.sin_port = htons(9999);    //端口复用,防止服务器重启时之前绑定的端口还没有释放    //程序突然退出而系统没有释放端口    int optval = 1;    setsockopt(lfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));        //绑定    int ret = bind(lfd, (struct sockaddr*)&seraddr, sizeof(seraddr));    if(ret == -1) {        perror("bind");        return -1;    }    //监听    ret = listen(lfd, 8);    if(ret == -1) {        perror("listen");        return -1;    }    //接收客户端连接    struct sockaddr_in cliaddr;    socklen_t len = sizeof(cliaddr);    int cfd = accept(lfd, (struct sockaddr*)&cliaddr, &len);    if(cfd == -1) {        perror("accept");        return -1;    }    //获取客户端信息    char clilp[16];    inet_ntop(AF_INET, &cliaddr.sin_addr.s_addr, clilp, sizeof(clilp));    int cliPort = ntohs(cliaddr.sin_port);    //printf("client's ip is%s, ans port is %d\n", clilp, cliPort);    //接收客户端发来的数据    char recvBuf[1024] = {0};    while(1) {        int len = recv(cfd, recvBuf, sizeof(recvBuf), 0);        if(len == -1) {            perror("recv");            return -1;        }else if(len == 0) {            printf("客户端已经断开连接……\n");            break;        }else if(len > 0) {            printf("read buf = %s\n", recvBuf);        }        char sendBuf[1024] = {0};        fgets(sendBuf, sizeof(sendBuf), stdin);        //大写字符串发送给客户端        ret = send(cfd, sendBuf, strlen(sendBuf) + 1, 0);        if(ret == -1) {            perror("send");            return -1;        }    }    close(cfd);    close(lfd);    return 0;}

在linux编译即可

g++  客户端.cpp -o a.out

g++  服务端.cpp -o b.out

来源地址:https://blog.csdn.net/weixin_58183566/article/details/130054991

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-服务器
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯