Linux下的套接字通信

套接字通信基本流程图:
在这里插入图片描述
服务端首先需要使用socket()创建套接字的文件描述符,然后bind()为套接字绑定IP地址和端口号,供客户端进行连接;
有了IP和端口号后,便开始使用listen()监听数据。
其中的固定格式为sockaddr,但为了方便一般使用sockaddr_in。
在这里插入图片描述
accept()用来准备和客户端连接,该函数是阻塞函数,当没有客户端连接时,会一直阻塞;且一次只能连接一个客户端。
recv()和send()成对使用,分别用来响应和发送数据。
close()用来关闭文件描述符,即关闭连接。

客户端同样需要创建一个套接字的文件描述符,但不需要绑定IP和端口号,connect()会自动寻找一个未被使用的端口号给客户端通信。

服务端:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h>

int main()
{
        //创建监听套接字
        int fd = socket(AF_INET,SOCK_STREAM,0);
        if(fd == -1)
        {
                perror("socket");
                return -1;
        }
        //绑定ip 端口号
        struct sockaddr_in saddr;
        saddr.sin_family = AF_INET; //协议簇
        saddr.sin_port = htons(9999); //端口号 主机转网络字节序
        saddr.sin_addr.s_addr = INADDR_ANY; //自动识别IP
        int ret = bind(fd,(struct sockaddr*)&saddr,sizeof(saddr));
        if(ret == -1)
        {
                perror("bind");
                return -1;
        }
        //开始监听
        ret = listen(fd,128);
        if(ret == -1)
        {
                perror("listen");
                return -1;
        }
        //准备接受客户端连接
        struct sockaddr_in caddr;
        int addrlen = sizeof(caddr);
        int cfd = accept(fd,(struct sockaddr*)&caddr,&addrlen);
        if(cfd == -1)
        {
                perror("accept");
                return -1;
        }
         //连接成功,打印客户端ip 和 端口号
        char ip[32];
        printf("IP地址:%s,端口:%d\n",
                        inet_ntop(AF_INET,&caddr.sin_addr.s_addr,ip,sizeof(ip)),
                        ntohs(caddr.sin_port));
        //通信
        while(1)
        {
                //接收数据
                char buff[1024];
                int len = recv(cfd,buff,sizeof(buff),0);
                if(len > 0)
                {
                        printf("client data: %s\n",buff);
                        send(cfd,buff,len,0);
                }
                else if(len == 0)
                {
                        printf("断开连接\n");
                        break;
                }
                else
                {
                        perror("recv");
                        break;
                }
        }
        //结束连接 
        close(fd);
        close(cfd);
        return 0;
}


客户端:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h>

int main()
{
        //创建通信套接字
        int fd = socket(AF_INET,SOCK_STREAM,0);
        if(fd == -1)
        {
                perror("socket");
                return -1;
        }
        //连接服务器
        struct sockaddr_in saddr;
        saddr.sin_family = AF_INET; //协议簇
        saddr.sin_port = htons(9999); //端口号 主机转网络字节序
        inet_pton(AF_INET,"192.168.212.128",&saddr.sin_addr.s_addr);
        int ret = connect(fd,(struct sockaddr*)&saddr,sizeof(saddr));
        if(ret == -1)
        {
                perror("connect");
                return -1;
        }
        //通信
        int number = 0;
        while(1)
        {
                //发送数据
                char buff[1024];
                sprintf(buff,"你好,hello,world,%d...\n",number++);
                send(fd,buff,strlen(buff)+1,0);
                //接收数据
                memset(buff,0,sizeof(buff));
                int len = recv(fd,buff,sizeof(buff),0);
                if(len > 0)
                {
                        printf("server data: %s\n",buff);
                }
                else if(len == 0)
                {
                        printf("断开连接\n");
                        break;
                }
                else
                {
                        perror("recv");
                        break;
                }
                sleep(1);
        }
        //结束连接 
        close(fd);
        return 0;
}

先启动服务端程序:

在这里插入图片描述
再启动客户端:
在这里插入图片描述
结果如下:
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

库巴巴星人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值