一、实验目的与要求:

(一)实验目的

该实验为设计性实验,实验目的如下:

  1. 了解本地计算机的网络配置。
  2. 熟悉面向对象编程/C编程环境,能够编写简单程序。
  3. 熟练网络查阅源代码资源并会调试,修改,测试。

(二)实验要求

  1. 本实验一人一组,编程语言为C/C++/C#/JAVA。
  2. 要求学生熟练掌握C/C++/C#/JAVA语言编程,多线程编程。
  3. 实验报告要求:
    • 实验报告要求包括实验目的、实验要求、实验内容(系统的设计和实现)、实验结果分析和实验体会等,重点在于实验内容(系统的设计和实现)和实验结果分析。实验报告要求上传和打印。
    • 写出系统设计和实现过程中的心得和体会,并回答实验中的思考题。
    • 实验报告撰写规范请见附。

 

二、实验内容、步骤及结论

(一)实验内容

  1. 实现简单的基于TCP或UDP的通信程序(控制台和视窗都可以),要求使用VC/JAVA/C#编程。
  2. 对完成的socket通信进行安全性设置,4项任选2项实现(1.做用户验证(用户未注册或者密码不正确,就断开连接)2.加密信息内容3.超时机制4.黑名单机制)。

(二)代码:https://segmentfault.com/a/1190000000736700

1.服务器端server.c

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "aes_options.h" //add

int main()
{
	int server_fd;
	int client_fd;
	int len;
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	int sin_size;
	char buffer[BUFSIZ];
	// printf("%d",BUFSIZ);
	memset(&server_addr, 0, sizeof(server_addr)); // initialize struct
	memset(&server_addr, 0, sizeof(client_addr));

	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = INADDR_ANY;
	server_addr.sin_port = htons(9000);

	if ((server_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) // create server socket
	{
		perror("socket create failed");
		return 1;
	}

	if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0) // bind info on server socket
	{
		perror("bind failed");
		return 1;
	}

	listen(server_fd, 5); // listen port 9000

	sin_size = sizeof(struct sockaddr_in);

	if ((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &sin_size)) < 0)
	{
		perror("accept failed");
		return 1;
	}

	printf("accept client %s\n", inet_ntoa(client_addr.sin_addr));
	len = send(client_fd, "Welcome to my server\n", 21, 0);

	while ((len = recv(client_fd, buffer, BUFSIZ, 0)) > 0)
	{

		char *decryto_string = NULL;		   // add
		decrypt(buffer, &decryto_string, len); // add
		printf("%s \n", decryto_string);
		if (send(client_fd, decryto_string, len, 0) < 0) // modified
		{
			perror("send failed");
			return 1;
		}
	}

	close(client_fd);
	close(server_fd);

	return 0;
}

2.客户端client.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include "aes_options.h"           //add

int main()
{
    int len;
    int client_sockfd;  
    struct sockaddr_in server_addr;
    char buffer[BUFSIZ];
    char *encrypt_string = NULL;
    memset(&server_addr, 0, sizeof(server_addr));

    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_addr.sin_port = htons(9000);

    if((client_sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror("socket create failed");
        return 1;

    }
    int username;
    int password;
    printf("enter the username:");
    scanf("%d", &username);
    printf("enter the password:");
    scanf("%d", &password);
    if (username !=2020 || password != 1212)
    {
        printf("uncorrect name!\n");
        return 1;
    }
    
    

    if(connect(client_sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0)
    {
        perror("connect failed");
        return 1;
    }

    printf("connect to server\n");
    len = recv(client_sockfd, buffer, BUFSIZ, 0);

    buffer[len] = '\0';
    printf("%s", buffer);

    while(1)
    {
        printf("enter a data:");
        scanf("%s", buffer);
        if(!strcmp(buffer,"quit"))
            break;
        int encrypt_length = encrypt(buffer, &encrypt_string);     //add
        len = send(client_sockfd, encrypt_string, encrypt_length, 0); //add
        len = recv(client_sockfd, buffer, BUFSIZ, 0);
        buffer[len] = '\0';
        printf("recived:%s \n", buffer);
    }

    close(client_sockfd);
    printf("bye");


    return 0;
}

/*char username;
    int password;
    printf("enter the username:");
    scanf("%s", &username);
    printf("enter the password:");
    scanf("%d", &password);
    if (username != "ycy" || password != 20201212)
    {
        printf("uncorrect name!\n");
        return 1;
    }
    */

3.加密解密函数openssl.c

#include <stdio.h>
#include <openssl/aes.h>
#include <stdlib.h>
#include <string.h>

int encrypt(char *input_string, char **encrypt_string)
{
    AES_KEY aes;
    unsigned char key[AES_BLOCK_SIZE]; // AES_BLOCK_SIZE = 16
    unsigned char iv[AES_BLOCK_SIZE];  // init vector
    unsigned int len;                  // encrypt length (in multiple of AES_BLOCK_SIZE)
    unsigned int i;
    // set the encryption length
    len = 0;
    if ((strlen(input_string) + 1) % AES_BLOCK_SIZE == 0)
    {
        len = strlen(input_string) + 1;
    }
    else
    {
        len = ((strlen(input_string) + 1) / AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE;
    }
    // Generate AES 128-bit key
    for (i = 0; i < 16; ++i)
    {
        key[i] = 32 + i;
    }
    // Set encryption key
    for (i = 0; i < AES_BLOCK_SIZE; ++i)
    {
        iv[i] = 0;
    }
    if (AES_set_encrypt_key(key, 128, &aes) < 0)
    {
        fprintf(stderr, "Unable to set encryption key in AES\n");
        exit(0);
    }
    // alloc encrypt_string
    *encrypt_string = (unsigned char *)calloc(len, sizeof(unsigned char));
    if (*encrypt_string == NULL)
    {
        fprintf(stderr, "Unable to allocate memory for encrypt_string\n");
        exit(-1);
    }
    // encrypt (iv will change)
    AES_cbc_encrypt(input_string, *encrypt_string, len, &aes, iv, AES_ENCRYPT);
    return len;
}
void decrypt(char *encrypt_string, char **decrypt_string, int len)
{
    unsigned char key[AES_BLOCK_SIZE]; // AES_BLOCK_SIZE = 16
    unsigned char iv[AES_BLOCK_SIZE];  // init vector
    AES_KEY aes;
    int i;
    // Generate AES 128-bit key
    for (i = 0; i < 16; ++i)
    {
        key[i] = 32 + i;
    }
    // alloc decrypt_string
    *decrypt_string = (unsigned char *)calloc(len, sizeof(unsigned char));
    if (*decrypt_string == NULL)
    {
        fprintf(stderr, "Unable to allocate memory for decrypt_string\n");
        exit(-1);
    }
    // Set decryption key
    for (i = 0; i < AES_BLOCK_SIZE; ++i)
    {
        iv[i] = 0;
    }
    if (AES_set_decrypt_key(key, 128, &aes) < 0)
    {
        fprintf(stderr, "Unable to set decryption key in AES\n");
        exit(-1);
    }
    // decrypt
    AES_cbc_encrypt(encrypt_string, *decrypt_string, len, &aes, iv,
                    AES_DECRYPT);
}

4.AES头文件aes_options.h

#ifndef _ASE_H_
#define _ASE_H_
	int encrypt(char *input_string, char **encrypt_string);
	void decrypt(char *encrypt_string, char **decrypt_string, int len);
#endif

(三)运行

gcc -I. openssl.c server.c -o server -lcrypto

gcc -I. openssl.c client.c -o client -lcrypto

先运行server,再运行client

输入quit退出

若用户名或密码错误,无法进入

 

三、实验体会

  微信、QQ、手机APP在进行网络连接时有何种安全措施?

  为了确保即时通讯的稳定性,采用了短链接(HTTP协议)和长链接(TCP协议)相结合的方式,分别应对状态协议和数据传输协议。短链接方式采用HTTP协议,主要用于用户登录信息验证、获取好友列表、用户头像、行为日志上报、刷新朋友圈等短期状态型的应用;长链接方式采用TCP协议,主要用于接收/发送文本消息、语音、图片、视频文件等传输过程需要保持连接状态的数据的传输。

  微信采用SYNC协议,是参考Activesync来实现的。SYNC是基于状态同步的协议,将信息的收发过程看作状态同步的过程。服务器每收到最新的消息或更新好友状态,都会将客户端与服务端消息进行同步。微信平台将交互模式简单化,只需要推送一个消息到达的通知,终端通过收到的通知进行信息同步。这种简化模式有利于微信在各种平台上的应用,通过状态差值同步数据的方式,获得最小的数据变更。同时,采用增量的传输模式得到最小的数据传输量。采用SYNC协议,可以确保信息是稳定传送、按序到达的。

原文地址:http://www.cnblogs.com/20201212ycy/p/16846180.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性