2019-2020 information security systems design basis 20,175,306 2,017,530,920,175,322 third experiment real-time systems

Purpose and procedures

Concurrent Programs -1

Requirements: Learn to use Linux commands wc (1)
design and implementation wc (1) server (port number is six after your student number) based on Linux Socket and clients
client transfer a text file to the server
server back to add a text file the number of words

 上方提交代码
 附件提交测试截图,至少要测试附件中的两个文件

(1) learning to use Linux command wc (1)
the first to use "find a man" command to learn wc command, that man wccommand to view the wc command

May know that wcthe command is used to count the number of bytes in the specified file, words, lines and direct output statistics
used directly wc+文件名.txtcommand it.

(2) Design wc file transfer service and client-based Socket program
works:

Client code:

#include<netinet/in.h>   // sockaddr_in  
#include<sys/types.h>    // socket  
#include<sys/socket.h>   // socket  
#include<stdio.h>        // printf  
#include<stdlib.h>       // exit  
#include<string.h>       // bzero  

#define SERVER_PORT 165235  
#define BUFFER_SIZE 1024  
#define FILE_NAME_MAX_SIZE 512  

int main()  
{  
    // 声明并初始化一个客户端的socket地址结构  
    struct sockaddr_in client_addr;  
    bzero(&client_addr, sizeof(client_addr));  
    client_addr.sin_family = AF_INET;  
    client_addr.sin_addr.s_addr = htons(INADDR_ANY);  
    client_addr.sin_port = htons(0);  

    // 创建socket,若成功,返回socket描述符  
    int client_socket_fd = socket(AF_INET, SOCK_STREAM, 0);  
    if(client_socket_fd < 0)  
    {  
        perror("Create Socket Failed:");  
        exit(1);  
    }  

    // 绑定客户端的socket和客户端的socket地址结构 非必需  
    if(-1 == (bind(client_socket_fd, (struct sockaddr*)&client_addr, sizeof(client_addr))))  
    {  
        perror("Client Bind Failed:");  
        exit(1);  
    }  

    // 声明一个服务器端的socket地址结构,并用服务器那边的IP地址及端口对其进行初始化,用于后面的连接  
    struct sockaddr_in server_addr;  
    bzero(&server_addr, sizeof(server_addr));  
    server_addr.sin_family = AF_INET;  
    if(inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr) == 0)  
    {  
        perror("Server IP Address Error:");  
        exit(1);  
    }  
    server_addr.sin_port = htons(SERVER_PORT);  
    socklen_t server_addr_length = sizeof(server_addr);  

    // 向服务器发起连接,连接成功后client_socket_fd代表了客户端和服务器的一个socket连接  
    if(connect(client_socket_fd, (struct sockaddr*)&server_addr, server_addr_length) < 0)  
    {  
        perror("Can Not Connect To Server IP:");  
        exit(0);  
    }  

    // 输入文件名,并放到缓冲区buffer中等待发送  
    char file_name[FILE_NAME_MAX_SIZE+1];  
    bzero(file_name, FILE_NAME_MAX_SIZE+1);  

    printf("Please Input File Name On Client:\t");
    scanf("%s", file_name);  

    char buffer[BUFFER_SIZE];  
    bzero(buffer, BUFFER_SIZE);  
    strncpy(buffer, file_name, strlen(file_name)>BUFFER_SIZE?BUFFER_SIZE:strlen(file_name));  

    // 向服务器发送buffer中的数据  
    if(send(client_socket_fd, buffer, BUFFER_SIZE, 0) < 0)  
    {  
        perror("Send File Name Failed:");  
        exit(1);  
    }  


    // 打开文件并读取文件数据  
        FILE *fp = fopen(file_name, "r");  
        if(NULL == fp)  
        {  
            printf("File:%s Not Found\n", file_name);  
        }  
        else  
        {  
            bzero(buffer, BUFFER_SIZE);  
            int length = 0;  
            // 每读取一段数据,便将其发送给服务器,循环直到文件读完为止  
            while((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)  
            {  
                if(send(client_socket_fd, buffer, length, 0) < 0)  
                {  
                    printf("Send File:%s Failed./n", file_name);  
                    break;  
                }  
                bzero(buffer, BUFFER_SIZE);  
            }  

            // 关闭文件  

            fclose(fp);  
            printf("File:%s Transfer Successful!\n", file_name);  
        char s[50]; 
        scanf("%s",s);
        send(client_socket_fd,"OK",BUFFER_SIZE,0);
        recv(client_socket_fd,buffer,BUFFER_SIZE,0);    
        printf("%d words.\n",atoi(buffer));
    }  

    close(client_socket_fd);  
    return 0;  
} 

Service-Terminal

#include<netinet/in.h>  // sockaddr_in  
#include<sys/types.h>   // socket  
#include<sys/socket.h>  // socket  
#include<stdio.h>       // printf  
#include<stdlib.h>      // exit  
#include<string.h>      // bzero  

#define SERVER_PORT 165235  
#define LENGTH_OF_LISTEN_QUEUE 20  
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512  

int main(void)  
{  
    // 声明并初始化一个服务器端的socket地址结构  
    struct sockaddr_in server_addr;  
    bzero(&server_addr, sizeof(server_addr));  
    server_addr.sin_family = AF_INET;  
    server_addr.sin_addr.s_addr = htons(INADDR_ANY);  
    server_addr.sin_port = htons(SERVER_PORT);  

    // 创建socket,若成功,返回socket描述符  
    int server_socket_fd = socket(PF_INET, SOCK_STREAM, 0);  
    if(server_socket_fd < 0)  
    {  
        perror("Create Socket Failed:");  
        exit(1);  
    }  
    int opt = 1;  
    setsockopt(server_socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));  

    // 绑定socket和socket地址结构  
    if(-1 == (bind(server_socket_fd, (struct sockaddr*)&server_addr, sizeof(server_addr))))  
    {  
        perror("Server Bind Failed:");  
        exit(1);  
    }  

    // socket监听  
    if(-1 == (listen(server_socket_fd, LENGTH_OF_LISTEN_QUEUE)))  
    {  
        perror("Server Listen Failed:");  
        exit(1);  
    }  

    while(1)  
    {  
        // 定义客户端的socket地址结构  
        struct sockaddr_in client_addr;  
        socklen_t client_addr_length = sizeof(client_addr);  

        // 接受连接请求,返回一个新的socket(描述符),这个新socket用于同连接的客户端通信  
        // accept函数会把连接到的客户端信息写到client_addr中  
        int new_server_socket_fd = accept(server_socket_fd, (struct sockaddr*)&client_addr, &client_addr_length);  
        if(new_server_socket_fd < 0)  
        {  
            perror("Server Accept Failed:");  
            break;  
        }  

       // recv函数接收数据到缓冲区buffer中  
        char buffer[BUFFER_SIZE];  
        bzero(buffer, BUFFER_SIZE);  
        if(recv(new_server_socket_fd, buffer, BUFFER_SIZE, 0) < 0)  
        {  
            perror("Server Recieve Data Failed:");  
            break;  
        }  

        // 然后从buffer(缓冲区)拷贝到file_name中  
        char file_name[FILE_NAME_MAX_SIZE+1];  
        bzero(file_name, FILE_NAME_MAX_SIZE+1);  
        strncpy(file_name, buffer, strlen(buffer)>FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE:strlen(buffer));  
        printf("%s\n", file_name);  

    // 打开文件,准备写入  
        FILE *fp = fopen(file_name, "w");  
        if(NULL == fp)  
        {  
            printf("File:\t%s Can Not Open To Write\n", file_name);  
            exit(1);  
        }  

    // 从客户端接收数据到buffer中  
        // 每接收一段数据,便将其写入文件中,循环直到文件接收完并写完为止  
        bzero(buffer, BUFFER_SIZE);  
        int length = 0;  
        while((length = recv(new_server_socket_fd, buffer, BUFFER_SIZE, 0)) > 0)  
        {  
        if(strcmp(buffer,"OK")==0) break;
            if(fwrite(buffer, sizeof(char), length, fp) < length)  
            {  
                printf("File:\t%s Write Failed\n", file_name);  
                break;  
            }  
            bzero(buffer, BUFFER_SIZE);  
        }  


    // 接收成功后,关闭文件,关闭socket  
        printf("Receive File:\t%s From Client IP Successful!\n", file_name);  
        fclose(fp);


    // 统计文件单词个数,并发送给客户端
    int words=0;
    char s[100];
    FILE *fp2;
    if((fp2=fopen(file_name,"r"))==NULL){
        printf("ERROR!\n");
        exit(0);
    }
    while(fscanf(fp2,"%s",s)!=EOF)
        words++;
    fclose(fp2);
    //printf("%d words.\n",words);


    sprintf(buffer,"%d",words);

    send(new_server_socket_fd,buffer,BUFFER_SIZE,0);

    //send(new_server_socket_fd,&words,sizeof(words),0);
    close(new_server_socket_fd);  



        // 关闭与客户端的连接  

    }  
    // 关闭监听用的socket  
    close(server_socket_fd);  
    return 0;  
} 

Test shots.

Concurrent Program -2

Requirements: Using multithreading wc servers and use synchronous mutual exclusion mechanism to ensure the correct count
submit the above code
below to submit a test
comparing the performance of single-threaded version, and analyze the reasons.
The basic steps:
the server to create a ServerSocket bound port number, cycle call accept () method.
The client creates a socket and requests and server-side connection.
The server accepts client requests to create a socket connection is established with the client.
Two socket calls on a separate thread.
The server continues to wait for a new connection when there is a new client and server connections, creates a new socket and inside this thread communication.
And to add compile time -lpthreadoption specifies the need to link the thread library, you create a new socket and inside this thread communication.

Add a header filehead.h

#ifndef HEAD_H
#define HEAD_H
int wcfunc(char *file_name);
#endif

Client:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "head.h"
#define BUFFER_SIZE 1024  
#define FILE_NAME_MAX_SIZE 512 

static void usage(const char* proc)
{
    printf("%s[server_ip][server_port]\n", proc);
}

//./client server_ip, server_port
int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        usage(argv[0]);
        return 1;
    }
    //1.创建sock
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock < 0)
    {
        perror("socket");
        return 2;
    }
    //2.connect
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_port = htons(atoi(argv[2]));
    //将点分十进制的字符串转换成能在网络上传输的网络号
    server.sin_addr.s_addr = inet_addr(argv[1]);
    //调用connect,第一个参数是客户端的socket套接字,第二个参数是服务器端套接字
    if(connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0)
    {
        perror("connect");
        return 2;
    }
    /*//先写后读
    char buf[1024];
    while(1)
    {
        printf("Please enter# ");
        fflush(stdout);
        //读取标准输入键盘中的数据
        ssize_t s = read(0, buf, sizeof(buf) - 1);
        if(s > 0)
        {
            buf[s - 1] = 0;
            //将buf中的内容写到套接字中
            write(sock, buf, strlen(buf));
            //读取服务器的响应
            ssize_t _s = read(sock, buf, sizeof(buf)-1);
            if(_s > 0)
            {
                buf[_s] = 0;
                printf("server ech0# %s\n", buf);
            }
        }
    }*/
    char file_name[FILE_NAME_MAX_SIZE+1];  
    bzero(file_name, FILE_NAME_MAX_SIZE+1);  
    printf("Please Input File Name On Client: ");
    scanf("%s", file_name);  
    char buffer[BUFFER_SIZE];  
    bzero(buffer, BUFFER_SIZE);  
    strncpy(buffer, file_name, strlen(file_name)>BUFFER_SIZE?BUFFER_SIZE:strlen(file_name));  
    if(send(sock, buffer, BUFFER_SIZE, 0) < 0)  
    {
    perror("Send File Name Failed!");
    exit(1);  
    }
    FILE *fp = fopen(file_name, "r");  
    if(NULL == fp)  
    {  
        printf("File: %s Not Found!\n", file_name);  
    }  
    else  
    {  
        bzero(buffer, BUFFER_SIZE);  
        int length = 0;  
        while((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
        {
            if(send(sock, buffer, length, 0) < 0)  
            {  
                printf("Send File: %s Failed!/n", file_name);  
                break;  
            }  
            bzero(buffer, BUFFER_SIZE);  
        }  
    printf("Send File: %s Successful!\n", file_name);
    printf("The File has %d words.\n",wcfunc(file_name));     
    }
    fclose(fp);
    close(sock);
    return 0;
}

int wcfunc(char *file_name)
{
    int t;
    int w = 0;
    int state = 0;
    FILE *in;
    if((in = fopen(file_name,"r"))==NULL)
    {
        printf("wc %s:no this file or dir\n",file_name);
        return 0;
    }
    while((t=fgetc(in))!=EOF)
    {
        
        if(t=='\n'||t==' '||t=='\r') {
                    state = 0;
                    continue;
            } else {
                    if(state == 0) {
                    state = 1;
                    w++;
                }
                    continue;
            }
    }
    return w;
}

Service-Terminal

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512
static void Usage(char* proc)
{
    printf("%s[local_ip], [local_port]\n", proc);
}
int startup(char* _ip, int _port)
{
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock < 0)
    {
        perror("socket");
        return 1;
    }
    struct sockaddr_in local;//初始化协议地址
    local.sin_family = AF_INET;
    local.sin_port = htons(_port);
    local.sin_addr.s_addr = inet_addr(_ip);
    //将套接字和tcp服务绑定(服务端ip地址)
    if(bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0)
    {
        perror("bind");
        exit(3);
    }
    //监听这个套接字,监听指定端口,第二个参数表示可以排队连接的最大个数
    if(listen(sock, 5) < 0)
    {
        perror("listen");
    }
    return sock;
}
void* handle(void* argc)
{
    int newsock = (int)argc;
    char buf[1024];
    while(1)
    {
        int s = read(newsock, buf, sizeof(buf) - 1);
        if(s > 0)
        {
            buf[s] = 0;
            printf("client# %s\n", buf);
            write(newsock, buf, strlen(buf));//服务器回显
        }
        else if(s == 0)
        {
            printf("client quit\n");
        }
        else
        {
            break;
        }
    }
    close(newsock);
}
//argv[]指针数组,指向各个参数
int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        Usage(argv[0]);
        return 2;
    }
    int listen_sock = startup(argv[1], atoi(argv[2]));
    //printf("sock:%d\n", listen_sock);
    //需要让子进程的子进程去提供服务
    //父进程继续监听
    char buf[1024];
    while(1)
    {
        struct sockaddr_in client;
        socklen_t len = sizeof(client);
        int newsock = accept(listen_sock, (struct sockaddr*)&client, &len);
        if(newsock < 0)
        {
            perror("accept");
            continue;
        }
        //将网络中的数据转换为主机用户可以看懂的数据
        printf("get a new client %s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
        //创建一个新的线程去服务
        //主线程只负责监听工作
        pthread_t tid;
        //pthread_create(&tid, NULL, handle, (void*)newsock);
        pthread_detach(tid);

    /*char buffer[BUFFER_SIZE]; 
    bzero(buffer, BUFFER_SIZE); 
    char file_name[FILE_NAME_MAX_SIZE+1];  
    bzero(file_name, FILE_NAME_MAX_SIZE+1);  
        strncpy(file_name, buffer, strlen(buffer)>FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE:strlen(buffer));  
    printf("%s\n", file_name);  
        FILE *fp = fopen(file_name, "w");  
        if(NULL == fp)  
        {  
        printf("File: %s Can Not Open To Write\n", file_name);  
        exit(1);  
        }  
    bzero(buffer, BUFFER_SIZE);  
        int length = 0;  
        while((length = recv(newsock, buffer, BUFFER_SIZE, 0)) > 0)  
        {  
        if(strcmp(buffer,"OK")==0) 
        break;
        if(fwrite(buffer, sizeof(char), length, fp) < length)  
        {  
        printf("File: %s Write Failed!\n", file_name);  
            break;  
        }  
            bzero(buffer, BUFFER_SIZE);  
    }  
        printf("Receive File: %s From Client Successful!\n", file_name);  
        fclose(fp);

    int words=0;
    char s[100];
    FILE *fp2;
    if((fp2=fopen(file_name,"r"))==NULL)
    {
        printf("ERROR!\n");
        exit(0);
    }
    while(fscanf(fp2,"%s",s)!=EOF)
    words++;
    fclose(fp2);
    printf("%d words.\n",words);
    char sendbuf[50];
    sprintf(sendbuf,"%d",words);
    send(newsock,sendbuf,50,0);
        close(newsock);*/
    }
    close(listen_sock);
    return 0;
}

Screenshot results:

Comparing single-threaded version, multi-threaded shorter response time than single-threaded, faster, better use of CPU. Because a single thread must be an executive order, no front thread of execution can not be completed the next one; and multi-threaded CPU can analyze whether there are spare, it can determine whether to execute multiple threads simultaneously, so that not only shorten the time, and more good use of the CPU.

Concurrent Programs -3

Requirements: Cross-build a multithreaded version of the server and deployed to the test chamber
the PC as a client server test wc
submit test shots.

The first two experiments done very well, I did not expect last there is a problem, is the experimental box and a host of ping nowhere, probably commissioning half an hour and no fruit, and finally had to regret away. We are also very puzzled, because the first time we experiment only once to get, done very well, this time not worked, change box, change the cable can not be solved, we are very worried this matter .

Experimental thoughts

The experiment is concurrent program, three steps, first let us use the wc command to view the number of words in the file, and sockets are learning program we recently have many similarities, both client and server joint customer service . The second is a multi-process on the basis of the first, the first two are not too difficult, as long as the code is correct can be completed on your computer. The third part is on the test box is completed, we encountered great difficulties, step by step, through exclusion, not yet completed, experimental box and the computer has been in a state of ping nowhere. Through this experiment, we learned how to use Linux commands wc, problems encountered in this experiment, we will summarize the reflection, study and find out why the computer can not connect test box and carefully in the next experiment.

Guess you like

Origin www.cnblogs.com/20175309lyh/p/11918799.html