服务器通信实现代码

#include "myhead.h"

/*
    tcp双向通信--》服务器的代码
    多路复用使用思路:
        1.思考要监测什么文件描述符 --》新的套接字(接收)
                                   --》键盘(发生)
        2.监测新套接字的读就绪
          监测键盘的读就绪
*/
int main()
{
    int tcpsock;
    int newsock;
    int ret;
    char rbuf[100];
    char sbuf[100];
    
    //定义ipv4地址体变量存放需要绑定的ip和端口号
    struct sockaddr_in bindaddr;
    bzero(&bindaddr,sizeof(bindaddr));
    bindaddr.sin_family=AF_INET;
    bindaddr.sin_addr.s_addr=htonl(INADDR_ANY); //女朋友(服务器)自己的ip
    bindaddr.sin_port=htons(20000); //女朋友(服务器)的端口号
    
    //定义ipv4地址体变量存放客户端的ip和端口号
    struct sockaddr_in boyaddr;
    int addrsize=sizeof(boyaddr);
    
    //创建tcp套接字
    tcpsock=socket(AF_INET,SOCK_STREAM,0);
    if(tcpsock==-1)
    {
        perror("创建tcp套接字失败!\n");
        return -1;
    }
    
    int on=1;
    setsockopt(tcpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
    
    //绑定女朋友(服务器)自己的ip和端口号
    ret=bind(tcpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
    if(ret==-1)
    {
        perror("绑定ip端口失败了!\n");
        return -1;
    }
    
    //监听
    ret=listen(tcpsock,5);
    if(ret==-1)
    {
        perror("监听失败!\n");
        return -1;
    }
    printf("旧的套接字(监听套接字)是:%d\n",tcpsock);
    printf("服务器的代码阻塞在accept位置了!\n");
    //接收客户端的连接请求
    newsock=accept(tcpsock,(struct sockaddr *)&boyaddr,&addrsize);  
    if(newsock==-1)
    {
        perror("接收连接请求失败了!\n");
        return -1;
    }
    printf("有一个客户端连接成功了,产生的新套接字(已连接套接字)是:%d\n",newsock);
    
    fd_set myset;
    
    while(1)
    {
        //由于select会自动剔除没有发送状态改变的文件描述符,所有需要重复添加
        FD_ZERO(&myset);
        FD_SET(newsock,&myset);
        FD_SET(0,&myset);
        //调用select监测新的套接字是否有数据可读,键盘是否有输入
        ret=select(newsock+1,&myset,NULL,NULL,NULL);
        if(ret>0) //监测到了状态变化
        {
            //进一步判断究竟是谁(键盘or新的套接字)发生了读就绪
            if(FD_ISSET(newsock,&myset)) //newsock在集合--》newsock发生了读就绪
            {
                bzero(rbuf,100);
                //接收客户端发过来的信息
                read(newsock,rbuf,100);
                printf("客户端发送过来的内容是:%s\n",rbuf);
            }
            if(FD_ISSET(0,&myset)) //键盘在集合--》键盘发生了读就绪
            {
                bzero(sbuf,100);
                scanf("%s",sbuf);
                write(newsock,sbuf,strlen(sbuf));
            }
        }
        else 
        {
            perror("监测失败!\n");
            return -1;
        }
    }
    //关闭套接字
    close(tcpsock);
    close(ret);
    return 0;
}

客户端通信实现代码

#include "myhead.h"

/*
    tcp双向通信--》客户端的代码
    多路复用使用思路:
        1.思考要监测什么文件描述符 --》键盘(跟发送有关)
                                   --》套接字(跟接收有关)
        2.监测键盘的读就绪
              套接字的读就绪
*/
int main()
{
    int tcpsock;
    int ret;
    char sbuf[100];
    char rbuf[100];
    //定义ipv4地址体变量存放需要绑定的ip和端口号
    struct sockaddr_in bindaddr;
    bzero(&bindaddr,sizeof(bindaddr));
    bindaddr.sin_family=AF_INET;
    bindaddr.sin_addr.s_addr=htonl(INADDR_ANY); //客户端自己的ip
    bindaddr.sin_port=htons(10000); //客户端的端口号
    
    //定义ipv4地址体变量存放女朋友(服务器)的ip和端口号
    struct sockaddr_in girladdr;
    bzero(&girladdr,sizeof(girladdr));
    girladdr.sin_family=AF_INET;
    girladdr.sin_addr.s_addr=inet_addr("192.168.22.9"); //服务器的ip
    girladdr.sin_port=htons(20000); //服务器的端口号
    
    //创建tcp套接字
    tcpsock=socket(AF_INET,SOCK_STREAM,0);
    if(tcpsock==-1)
    {
        perror("创建tcp套接字失败!\n");
        return -1;
    }
    
    int on=1;
    setsockopt(tcpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
    
    //绑定客户端自己的ip和端口号
    ret=bind(tcpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
    if(ret==-1)
    {
        perror("绑定ip端口失败了!\n");
        return -1;
    }
    
    //拨号连接服务器
    ret=connect(tcpsock,(struct sockaddr *)&girladdr,sizeof(girladdr));
    if(ret==-1)
    {
        perror("连接失败了!\n");
        return -1;
    }
    
    fd_set myset;
    
    while(1)
    {
        //由于select会自动剔除没有发送状态改变的文件描述符,所有需要重复添加
        FD_ZERO(&myset);
        FD_SET(0,&myset); //键盘
        FD_SET(tcpsock,&myset); //套接字
        //调用select监测键盘是否有输入,监测套接字是否有数据可读
        ret=select(tcpsock+1,&myset,NULL,NULL,NULL);
        if(ret>0) //监测到了状态变化
        {
            //进一步判断究竟是谁(键盘or套接字)发生了状态变化
            if(FD_ISSET(0,&myset)) //键盘在集合中--》键盘发生了读就绪
            {
                bzero(sbuf,100);
                //读取键盘的输入
                scanf("%s",sbuf);
                //发送给服务器
                write(tcpsock,sbuf,strlen(sbuf));
            }
            if(FD_ISSET(tcpsock,&myset)) //套接字在集合中--》套接字发生了读就绪
            {
                bzero(rbuf,100);
                read(tcpsock,rbuf,100);
                printf("服务器发过来的信息是:%s\n",rbuf);
            }
        }
        else 
        {
            perror("监测失败!\n");
            return -1;
        }
    }
    
    //关闭套接字
    close(tcpsock);
    return 0;
    

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信