网络编程之socket双方聊天练习

双方聊天:

服务器demo

#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>

int main(int argc,char** argv){
    int s_fd,c_fd,fd;
    int c_len;
    char buf[1024] = {0};
    char msg[1024] = {0};
    struct sockaddr_in s_addr;
    struct sockaddr_in c_addr;
    memset(&s_addr,0,sizeof(struct sockaddr_in));
    memset(&c_addr,0,sizeof(struct sockaddr_in)); 

    if(argc != 3){
        printf("Param wrong!\n");
        exit(0);
    }
    //1.socket
    s_fd = socket(AF_INET,SOCK_STREAM,0);
    if(s_fd == -1){
        perror("socket");
        exit(-1);
    }
    //2.bind
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(atoi(argv[2]));
    inet_aton(argv[1],&s_addr.sin_addr);
    int ret = bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));
    if(ret == -1){
        perror("bind");
        exit(-2);
    }
    //3.listen
    listen(s_fd,10);
    //4.while(){ 1.accept 2.fork{1.read  2.write} }
    while(1){
        c_len = sizeof(struct sockaddr_in);
        c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&c_len);
        if(c_fd == -1){
            perror("accpet");
            exit(-41);
        }else{
            printf("%s connected!\n",inet_ntoa(c_addr.sin_addr));
        }
        while(1){
            fd = fork();
            if(fd == 0){
                while(1){
                	memset(msg,0,sizeof(msg));
            		gets(msg);
            		write(c_fd,msg,strlen(msg));
            	}
            }
            while(1){
            	memset(buf,0,sizeof(buf));
            	read(c_fd,buf,1024);
            	printf("New message:%s\n",buf);
            }
        }
    }
    return 0;
} 

客户端demo:

#include <stdio.h>                                                                                                                                                     
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc,char** argv){
    
    int c_fd,fd;
    char msg[1024] = {0};
    char buf[1024] = {0};
    struct sockaddr_in c_addr;
    memset(&c_addr,0,sizeof(struct sockaddr_in));

    //1.socket
    c_fd = socket(AF_INET,SOCK_STREAM,0);
    if(c_fd == -1){
        perror("socket");
        exit(-1);
    }   
    //2.connect
    c_addr.sin_family = AF_INET;
    c_addr.sin_port = htons(atoi(argv[2]));
    inet_aton(argv[1],&c_addr.sin_addr);
    int ret = connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr_in));
    if(ret == -1){
        perror("connect");
        exit(-2);
    }   
    //3.while(1){fork  1.read 2.write}
    while(1){
        fd = fork();
        if(fd == 0){ 
            while(1){
            	memset(msg,0,sizeof(msg));
        		gets(msg);
        		write(c_fd,msg,strlen(msg));
        	}
        }   
        while(1){
			memset(buf,0,sizeof(buf));
        	read(c_fd,buf,1024);
        	printf("New message:%s\n",buf);
        }
    }   

    return 0;
}                                                                                                                                                                      
 ~

运行结果:
在这里插入图片描述
在这里插入图片描述
这个练习最主要的思考点就是在需要创建另外一个进程,也是fork其中的一个功能:在网络进程中,通常使用两个进程,一个接受另一用户的数据,而一个要负责给对方发送数据。而接受数据的进程是时时刻刻都要进行,所以程序中,fork完没有判断是否是父进程还是子进程,所以一直在等待接受数据,而发送消息的行为是要在间歇时间完成,所以先判断是否为子进程,在子进程中完成。

至于多人聊天,因为gets需要输入,也会阻塞进程,所以资源就会被一直抢占,有时输入的时候,被子进程抢占了,接受数据的进程便无法运行,于是无法正常接受数据,而是会卡在client和server之间的管道中。目前解决方法是:不要gets,直接printf一段话可以简单模拟多人聊天;还有一种方式是几个client在聊天,通过server来中转消息(QQ和微信原理就是这个)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值