网络编程:使用tcp协议实现服务器与客户端交互
创始人
2024-02-10 23:24:46

服务器

**************************************************************************************************************

#include
#include
#include
#include
#include
#include
#include

#define PTOR 6666
#define IP      "192.168.31.162"


#define ERR_MSG(msg)  do{\
    fprintf(stderr,"__%d__\n",__LINE__);\
    perror(msg);\
}while(0)


int main(int argc, const char *argv[])
{
    //1、创建流式套接字,返回值为文件描述符
    int sfd=socket(AF_INET,SOCK_STREAM,0);
    if(sfd<0)
    {
        ERR_MSG("socket");
        return -1;
    }


    //如果不加这段代码,则服务器异常退出后,会导致端口号在30s~3min内释放不出来
    //当程序结束后,想要让其他进程能够快速复用端口号,就可以使用下面的代码
    //允许端口快速被重用
    int reuse = 1;
    if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse ,sizeof(reuse)) < 0)
    {   
        ERR_MSG("setsockopt");
        return -1;                                                                                    
    }   
    printf("允许端口快速重用\n");


    //2、填充地址信息结构体,真实的地址信息结构体根据地址族制定
    struct sockaddr_in sin;
    sin.sin_family =AF_INET;//必须填AF_INET;
    sin.sin_port   =htons(PTOR);//网络字节序,端口号是2字节,所以用htons将主机字节序转为网络字节序
    sin.sin_addr.s_addr   =inet_addr(IP);//本机IP
    //printf("%d:%d_,%#x\n",__LINE__,htons(PTOR),inet_addr(IP));
    //3、将地址信息结构体绑定到套接字上
    if(bind(sfd,(struct sockaddr *)&sin,sizeof(sin))<0)
    {
        ERR_MSG("bind");
        return -1;
    }
    //4、将套接字设置为被动监听状态
    if(listen(sfd,128)<0)
    {
        ERR_MSG("listen");
        return -1;
    }
    printf("服务器设置被动监听设置成功\n");

    struct sockaddr_in cin;
    socklen_t  cinlen=sizeof(cin);
    //5、accept从队头获取一个客户端信息
    int newfd = accept(sfd,(struct sockaddr *)&cin,&cinlen);
    if(newfd<0)
    {
        ERR_MSG("accept");
        return -1;
    }
    printf("[%s:%d] newfd = %d 连接成功\n", \
            inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd);

    //6、数据传输
    char buf[32]="";
    ssize_t res=0;
    while(1)
    {
        //接收
        bzero(buf,sizeof(buf));

         res=recv(newfd,buf,sizeof(buf),0);
        if(res<0)
        {
            ERR_MSG("recv");
            return -1;
        }
        else if(0==res)
        {
            printf("newfd=%d 客户端关闭\n",newfd);
            break;
        }
        printf("res:%ld,newfd:%d,res:%s\n",res,newfd,buf);

        //发送
        //将发送一个数据到用户IP
        printf("服务器发送-->\n");
        fgets(buf,sizeof(buf),stdin);
        buf[sizeof(buf)-1]=0;
        if(send(newfd,buf,sizeof(buf),0)<0)
        {
            ERR_MSG("send");
            return -1;
        }
        bzero(buf,sizeof(buf));

        printf("send success\n");
    }
    close(newfd);
    close(sfd);
    return 0;
}
**************************************************************************************************************

客户端

**************************************************************************************************************

#include
#include
#include
#include
#include
#include
#include

#define ser_PTOR 6666
#define ser_IP      "192.168.31.162"


#define ERR_MSG(msg)  do{\
    fprintf(stderr,"__%d__\n",__LINE__);\
    perror(msg);\
}while(0)


int main(int argc, const char *argv[])
{
    //1、创建流式套接字,返回值为文件描述符
    int sfd=socket(AF_INET,SOCK_STREAM,0);
    if(sfd<0)
    {
        ERR_MSG("socket");
        return -1;
    }

    //绑定客户端自身IP和端口,到对应的套接字上;——非必要绑定
    //不绑定程序运行后操作系统会自动分配一个在49152—65535之间的端口号给套接字

    //填充地址信息结构体,真实地址信息结构体根据地址族来制定
    //struct sockaddr_in 

    //2、填充服务器的地址信息结构体,因为connect函数中要通过地址信息结构体来链接服务器
    struct sockaddr_in sin;
    sin.sin_family =AF_INET;//必须填AF_INET;
    sin.sin_port   =htons(ser_PTOR);//服务器绑定的端口
    sin.sin_addr.s_addr   =inet_addr(ser_IP);//服务器绑定的IP
    //注意,切换网络环境后IP是会发生改变的


    //3、连接服务器
    if(connect(sfd,(struct sockaddr *)&sin,sizeof(sin))<0)
    {
        ERR_MSG("connect");
        return -1;
    }
    printf("connect success\n");
    struct sockaddr_in cin;
    socklen_t  cinlen=sizeof(cin);
    //6、数据传输
    char buf[32]="";
    ssize_t res=0;
    while(1)
    {
        //发送
        //将获取到的数据拼接后发送回去
        printf("请输入-->\n");
        fgets(buf,sizeof(buf),stdin);
        buf[sizeof(buf)-1]=0;
        if(send(sfd,buf,sizeof(buf),0)<0)
        {
            ERR_MSG("send");
            return -1;
        }
        bzero(buf,sizeof(buf));
        printf("send success\n");

        //接收
        bzero(buf,sizeof(buf));
        res=recv(sfd,buf,sizeof(buf),0);
        if(res<0)
        {
            ERR_MSG("recv");
            return -1;
        }
        else if(0==res)
        {
            printf("sfd=%d 客户端关闭\n",sfd);
            break;
        }
        printf("res:%ld,sfd:%d,res:%s\n",res,sfd,buf);
    }
    close(sfd);
    return 0;
}
 

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...