【tcpip】ndk实现实现进程间通信

服务端

// tcp/ip server七步走
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>

#define NUM 1024//本服务器可以连接的最大客服端的个数


struct student
{
    int id;
    char a[20];
};

int main()
{
    //1.创建socket    socket()
    fd_set fdset;//描述符集合
    //int maxfd=-1;//最大文件描述符
    //int cfd[NUM];//客服端文件描述符数组
    int i,j;
    //int count=0;//客服端数量
    //char buf[1024];
    int sfd=socket(AF_INET,SOCK_STREAM,0);
    if(-1==sfd)perror("socket"),exit(-1);
    printf("creat socket success\n");

    //2.准备通信地址(服务器地址),使用结构体类型
    struct sockaddr_in addr;
    addr.sin_family=AF_INET;
    addr.sin_port=htons(10086);
    addr.sin_addr.s_addr=inet_addr("192.168.1.5");                //client也用这个server的地址

    //3.绑定socket和通信地址,使用bind()
    int r=bind(sfd, (struct sockaddr*)&addr,sizeof(addr));         //client用connect
    if(-1==r)
        perror("bind"),exit(-1);
    printf("bind success\n");
    
    //4.生成侦听socket:   listening socket  listen()                    //client可没有这一步
    r=listen(sfd,10);
    if(-1==r)perror("listen"),exit(-1);
    printf("listen success\n");

    //5.响应客户端连接请求并生成connected socket     accept()       //client当然没有这一步
    struct sockaddr_in recv_addr;
    socklen_t len=sizeof(recv_addr);
    int cfd=accept(sfd,(struct sockaddr*)&recv_addr,&len);
    if(-1==cfd)
        perror("accept"),exit(-1);

    char* ip=inet_ntoa(recv_addr.sin_addr); //存储client的ip
    printf("client$%s connect success\n",ip);
    printf("客户端端口号:%d\n",recv_addr.sin_port);


    /*while(1){
        FD_ZERO(&fdset);
        //把服务器描述符放入描述符号集合中。
        if(sfd != -1){
            FD_SET(sfd,&fdset);
            maxfd = maxfd > sfd ? maxfd : sfd; 
        }
        //把客户端描述符放入描述符号集合中。
        for(i=0;i<count;i++){
            if(cfd[i] != -1){
                FD_SET(cfd[i],&fdset);
                maxfd = maxfd > cfd[i] ? maxfd : cfd[i]; 
            }
        }
        //监视描述符号集合
        r = select(maxfd+1,&fdset,0,0,0);
        if(r > 0) printf("监视到有动静!\n");
        //如果有客户连接,就接收连接
        if(sfd!=-1 && 1 == FD_ISSET(sfd,&fdset)){
            cfd[count] = accept(sfd,0,0);
            if(cfd[count] > 0){
                printf("客户%d连接进来了!\n",cfd[count]);
                count++;
            }else{
                printf("客户端%d退出连接!\n",cfd[i]);
                close(cfd[i]);
                cfd[i] = -1;
                continue;
            }
        }
        //如果客户端发数据,就接收并广播
        for(i=0;i<count;i++){
            //找到发数据的客户端
            if(cfd[i] != -1 && 1 == FD_ISSET(cfd[i],&fdset) ){
                //接收其发送的数据
                r = read(cfd[i],buf,sizeof(buf)-1);
                if(r > 0){
                    buf[r] = 0;
                    printf("%d:%s\n",cfd[i],buf);
                    //广播给所有连接上服务器的客户端
                    for(j=0;j<count;j++){
                        if(cfd[j] != -1)
                            write(cfd[j],buf,strlen(buf));
                    }
                }else if(r == 0){
                    printf("网络异常,数据丢失!\n");
                }else{
                    printf("网络异常\n");
                }
            }
            
        }
    }

}*/

    //创建父子进程 进行通信
    if(fork())
    {
       
        char sendbuf[1024]={0};
        while(fgets(sendbuf,sizeof(sendbuf)-1,stdin)!=NULL)
        {
            write(cfd,sendbuf,sizeof(sendbuf)-1);
            memset(sendbuf,0,sizeof(sendbuf)-1);
        }
    }
    else 
    {
        //接受客服端发过来的信息    
        char revbuf[1024]={0};
        struct student stu;   
        read(cfd,&stu,sizeof(stu));
        printf("客服端的id号为:%d %s\n",stu.id,stu.a);
        //printf("客服端的姓名为:%s\n",stu.name);//存在一个乱码的问题
        while(1)
        {
            int ret=read(cfd,revbuf,sizeof(revbuf)-1);
            if(ret==0)
            {
                printf("客服端关闭连接\n");
                exit(-1);
            }
            else if(ret<0)
            {
                printf("读取数据失败\n");
                exit(-1);
            }
            fputs(revbuf,stdout);
            memset(revbuf,0,sizeof(revbuf)-1);
        }
    }
    close(cfd);
    close(sfd);
    return 0;
}

客户端














// tcp/ip server七步走
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <signal.h>

void handle(int num)
{
    printf("%d\n",num);
    exit(0);
}

struct student
{
    int id;
    char a[20];
};//结构体 用来发送id号给服务端

int main()
{
    //1.创建socket    socket()
    signal(SIGUSR1,handle);
    int sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(-1==sockfd)
        perror("socket"),exit(-1);
    printf("creat socket success\n");

    //2.准备通信地址(服务器地址),使用结构体类型
    struct sockaddr_in addr;
    addr.sin_family=AF_INET;
    addr.sin_port=htons(10086);
    addr.sin_addr.s_addr=inet_addr("192.168.1.5");

    int fd=connect(sockfd,(struct sockaddr*)&addr,sizeof(addr));
    if(-1==fd)
        printf("connect:%m\n");
    if(fork())
    {

        while(1)
        {
            //接收数据
            char revbuf[1024]={0};
            int ret=read(sockfd,revbuf,sizeof(revbuf)-1);
            if(ret==0)
            {
                printf("服务器关闭\n");
                close(sockfd);
                exit(-1);
            }
            else if(ret<0)
            {
                printf("接受数据:%m\n");
                close(sockfd);
                exit(-1);
            }
            fputs(revbuf,stdout);
            memset(revbuf,0,sizeof(revbuf)-1);
        }
        close(sockfd);
        kill(getpid(),SIGUSR1);//子进程收到服务器的关闭信息 杀死父进程
        exit(0);  
    }
   else
   {
        char sendbuf[1024]={0};
        struct student stu;
        stu.id=10;
        strcpy(stu.a, "abcdefgh");
        //stu.name="sun";
        printf("发送给服务器本机信息\n");
        write(sockfd,&stu,sizeof(stu));
        while(fgets(sendbuf,sizeof(sendbuf)-1,stdin)!=NULL)//从键盘读入数据
        {
            write(sockfd,sendbuf,sizeof(sendbuf)-1);
            memset(sendbuf,0,sizeof(sendbuf)-1);
        }
    }
    close(sockfd);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值