厦门大学计算机网络实验三

厦门大学计算机网络实验三

准备工作

1.安装本地echo服务,监听7号端口。我使用的是ubuntu虚拟机,修改的文件与centos7略有不同。

image-20211121110032815

可以看到我已经配置好了。(不会配置的可以搜索一下,ubuntu打开echo标准服务)

2.在ubuntu虚拟机编程太难受了,vscode使用ssh连接,在vscode里code和调试。image-20211121111352122

字符串逆序回送(TCP迭代)

1.成果展示:

客户端image-20211121110458104

服务器:image-20211121110551697

第一个客户端正常收发image-20211121110742726

第二个客户端等待

image-20211121110808728

收到bye后,立刻开始处理第二个客户端:

image-20211121110834432

image-20211121110906695

2.具体实现

在服务器端使用双重循环,内部有字符串处理

image-20211121111512073

客户端使用单个循环。

我还在对运行时参数做了处理,这样服务器和客户端就可以自定地址和端口号。

image-20211121111708557

3.为什么ip地址和端口号需要字节顺序转换?

htnol()函数其实很好理解,就是小端装换成大端,因为网络地址是大端,但计算机内存不一定与之一样,所以必须要转换。

字符串逆序回送(TCP并发)

1.先看实现成果

服务器端:image-20211121120639186

两个客户端

image-20211121120826868

image-20211121120836735

2.实验报告要求的三客户端:

image-20211121121803326

3.实现细节

  • 需要在子进程中关掉监听socketimage-20211121122056308
  • 在父进程关闭数据socketimage-20211121122137418
  • 一定要记得清楚僵尸进程image-20211121122203306

4.ppt问题。服务器accept之后会返回一个用于传输数据的socket,调用fork()会使父子进程同时拥有此socket描述符,父进程分支中是否需要关闭该socket?

答案是需要

若不关闭,在退出客户端后,还有多个网络连接在CLOSE_WAITimage-20211121123141693

基于UDP socket的简易聊天室

  1. 首先我了解了线程相关知识。
  • 守护线程:如果有一个线程必须设置为无限循环,那么该线程不结束,意味着整个python程序就不能结束,那为了能够让python程序正常退出,将这类无限循环的线程设置为守护线程,当程序当中仅仅剩下守护线程时,python程序就能够正常退出,不必关心这类线程是否执行完毕,这就是守护线程的意义。

  • 因为客户端需要一边发送,一边接受。就创建一个守护线程来控制接受信息。

  1. 成果图:

    服务器:image-20211122113657501

    客户端,检测用户名登录image-20211122114131574

    客户端,聊天内容image-20211122114237015

    客户端退出:image-20211122114302869

    捕获的异常(服务器突然关闭)image-20211122114437873

  2. 实现:客户端

    1. 创建两个线程,其中设定接受信息为守护线程

    2. image-20211122114603482

    3. 检测昵称

    4. image-20211122114810548

    5. 异常捕获

    6. image-20211122114851196

    7. 实现:服务器

      1. 初始化image-20211122115030316
      2. 接受信息image-20211122115051851
      3. 群发消息image-20211122115110302
      4. mainimage-20211122115135608
源代码
  • server1.c

    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <error.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[])
    {
         
    	int server_sock_listen, server_sock_data;
    	struct sockaddr_in server_addr;
    	char recv_msg[255];
    	char send_msg[255];
    	/* 创建socket */
    	server_sock_listen = socket(AF_INET, SOCK_STREAM, 0);
    
    	int i,port=0;    //port
        for (i=0;i< strlen(argv[2]);i++) {
         
            if(argv[2][i] != 0){
         
                port = port*10 + argv[2][i] - '0';
            }
        }
    	/* 指定服务器地址 */
    	server_addr.sin_family = AF_INET;
    	server_addr.sin_port = htons(port);
    	if(strcmp(argv[1],"localhost")==0){
         
    		server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY表示本机所有IP地址
    	}
    	else {
         
    		server_addr.sin_addr.s_addr = htonl(inet_addr(argv[1]));
    	}
    	memset(&server_addr.sin_zero, 0, sizeof(server_addr.sin_zero)); //零填充
    	/* 绑定socket与地址 */
    	bind(server_sock_listen, (struct sockaddr *)&server_addr, sizeof(server_addr));
    
    	/* 监听socket */
    	listen(server_sock_listen, 0);
    	printf("%s is listening:\n",argv[1]);
    	while(1) {
         
    		server_sock_data = accept(server_sock_listen, NULL, NULL);
    		printf("Accept.....\n");
    		while(1){
         
    			/* 接收并显示消息 */
    			memset(recv_msg, 0, sizeof(recv_msg)
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值