2018-2019-1 20165320 实验三 实时系统

Posted gst-paul

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018-2019-1 20165320 实验三 实时系统相关的知识,希望对你有一定的参考价值。

实验三

并发程序-1

  • 实验目标

    • 学习使用Linux命令wc(1)
    • 基于Linux Socket程序设计实现wc(1)服务器(端口号是你学号的后6位)和客户端
    • 客户端传一个文本文件给服务器
    • 服务器返加文本文件中的单词数
  • 运行截图:
    技术分享图片

  • 参考代码:

客户端:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>  
#define PORT 165320

#define MAXDATASIZE 100

int main(int argc, char *argv[])
{
    int sockfd, num;    
char buf[MAXDATASIZE];   
struct hostent *he;    
struct sockaddr_in server;

if (argc != 3)
{
    printf("Usage: %s <IP Address><Filename>
",argv[0]);
    exit(1);
}

if((he=gethostbyname(argv[1]))==NULL)
{
    printf("gethostbyname() error
");
    exit(1);
}

if((sockfd=socket(AF_INET,SOCK_STREAM, 0))==-1)
{
    printf("socket() error
");
    exit(1);
}
bzero(&server,sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr = *((struct in_addr *)he->h_addr);
if(connect(sockfd, (struct sockaddr *)&server, sizeof(server))==-1)
{
    printf("connect() error
");
    exit(1);
    }
char str[MAXDATASIZE] ;
strcpy(str,argv[2]);

if((num=send(sockfd,str,sizeof(str),0))==-1){
  printf("send() error
");
    exit(1);
}
if((num=recv(sockfd,buf,MAXDATASIZE,0))==-1)
{
    printf("recv() error
");
    exit(1);
}
buf[num-1]=‘‘;
printf("server message: %s
",buf);

close(sockfd);
return 0;
}

服务器:

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

#define PORT 165320

#define BACKLOG 1
#define MAXRECVLEN 1024

int main(int argc, char *argv[])
{
char buf[MAXRECVLEN];
int listenfd, connectfd;  
struct sockaddr_in server; 
struct sockaddr_in client; 
socklen_t addrlen;

if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{

    perror("socket() error. Failed to initiate a socket");
    exit(1);
}


int opt = SO_REUSEADDR;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

bzero(&server, sizeof(server));

server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(listenfd, (struct sockaddr *)&server, sizeof(server)) == -1)
{

    perror("Bind() error.");
    exit(1);
}

if(listen(listenfd, BACKLOG) == -1)
{
    perror("listen() error. 
");
    exit(1);
}

addrlen = sizeof(client);
while(1){
    if((connectfd=accept(listenfd,(struct sockaddr *)&client, &addrlen))==-1)
      {
        perror("accept() error. 
");
        exit(1);
      }
    FILE *stream;
    struct timeval tv;
    gettimeofday(&tv, NULL);
      printf("You got a connection from client‘s ip %s, port %d at time %ld.%ld
",inet_ntoa(client.sin_addr),htons(client.sin_port), tv.tv_sec,tv.tv_usec);
    
    int iret=-1;
    char d[1024];
     iret = recv(connectfd, buf, MAXRECVLEN, 0);
        if(iret>0)
        {
           strcpy(d,buf);
            stream = fopen(buf,"r");
            bzero(buf, sizeof(buf));
            strcat(buf,"单词数:");
            char s[21];
long int count = 0;
            while(fscanf(stream,"%s",s)!=EOF)
            count++;
            char str[10];
sprintf(str, "%ld", count); 
int n = sizeof(str);
str[n] = ‘‘; 
strcat(buf,"
");
strcat(buf,str);
strcat(buf,"(");
strcat(buf,d);
strcat(buf,"单词数)");strcat(buf,"
");
            
        }else
        {
            close(connectfd);
            break;
        }

        send(connectfd, buf, iret, 0); 
    }

close(listenfd);
return 0;
}

并发程序-2

  • 实验目标

    • 使用多线程实现wc服务器并使用同步互斥机制保证计数正确
    • 上方提交代码
    • 下方提交测试
    • 对比单线程版本的性能,并分析原因

    • 运行截图:
      技术分享图片

    • 参考代码:

服务器:

#include<stdlib.h>
#include<pthread.h>
#include<sys/socket.h>
#include<sys/types.h>       //pthread_t , pthread_attr_t and so on.
#include<stdio.h>
#include<netinet/in.h>      //structure sockaddr_in
#include<arpa/inet.h>       //Func : htonl; htons; ntohl; ntohs
#include<assert.h>          //Func :assert
#include<string.h>          //Func :memset bzero
#include<unistd.h>          //Func :close,write,read
#define SOCK_PORT 9988
#define BUFFER_LENGTH 1024
#define MAX_CONN_LIMIT 512     //MAX connection limit
static void Data_handle(void * sock_fd);   //Only can be seen in the file
int CountWordsOfEuropeanTxtFile(char *szFileName);
int CountWordsInOneLine(const char *szLine);
int main()
{
int sockfd_server;
int sockfd;
int fd_temp;
struct sockaddr_in s_addr_in;
struct sockaddr_in s_addr_client;
int client_length;
sockfd_server = socket(AF_INET,SOCK_STREAM,0);  //ipv4,TCP
assert(sockfd_server != -1);
//before bind(), set the attr of structure sockaddr.
memset(&s_addr_in,0,sizeof(s_addr_in));
s_addr_in.sin_family = AF_INET;
s_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);  //trans addr from uint32_t host byte order to network byte order.
s_addr_in.sin_port = htons(SOCK_PORT);          //trans port from uint16_t host byte order to network byte order.
fd_temp = bind(sockfd_server,(const struct sockaddr *)(&s_addr_in),sizeof(s_addr_in));
if(fd_temp == -1)
{
    fprintf(stderr,"bind error!
");
    exit(1);
}
fd_temp = listen(sockfd_server,MAX_CONN_LIMIT);
if(fd_temp == -1)
{
    fprintf(stderr,"listen error!
");
    exit(1);
}
while(1)
{
    printf("waiting for new connection...
");
    pthread_t thread_id;
    client_length = sizeof(s_addr_client);
    //Block here. Until server accpets a new connection.
    sockfd = accept(sockfd_server,(struct sockaddr * restrict)(&s_addr_client),(socklen_t *)(&client_length));
    if(sockfd == -1)
    {
        fprintf(stderr,"Accept error!
");
        continue;                               //ignore current socket ,continue while loop.
    }
    printf("A new connection occurs!
");
    if(pthread_create(&thread_id,NULL,(void *)(&Data_handle),(void *)(&sockfd)) == -1)
    {
        fprintf(stderr,"pthread_create error!
");
        break;                                  //break while loop
    }
}
//Clear
int ret = shutdown(sockfd_server,SHUT_WR); //shut down the all or part of a full-duplex connection.
assert(ret != -1);
printf("Server shuts down
");
return 0;
}
static void Data_handle(void * sock_fd)
{
int fd = *((int *)sock_fd);
int i_recvBytes;
char data_recv[BUFFER_LENGTH];
const char * data_send = "Server has received your request!
";
while(1)
{
    printf("waiting for file_name...
");
    //Reset data.
    memset(data_recv,0,BUFFER_LENGTH);
    i_recvBytes = read(fd,data_recv,BUFFER_LENGTH);
    if(i_recvBytes == 0)
    {
        printf("Maybe the client has closed
");
        break;
    }
    if(i_recvBytes == -1)
    {
        fprintf(stderr,"read error!
");
        break;
    }
    if(strcmp(data_recv,"quit")==0)
    {
        printf("Quit command!
");
        break;                           //Break the while loop.
    }
    printf("read from client : %s
",data_recv);
    
char buffer[BUFFER_LENGTH];
int count=0;
bzero(buffer, BUFFER_LENGTH);
count = CountWordsOfEuropeanTxtFile(data_recv);
sprintf(buffer,"%d", count);
    send(fd, buffer, sizeof(buffer), 0);
    if(write(fd,data_send,strlen(data_send)) == -1)
    {
        break;
    }
}
//Clear
printf("terminating current client_connection...
");
close(fd);            //close a file descriptor.
pthread_exit(NULL);   //terminate calling thread!
}
int CountWordsOfEuropeanTxtFile(char *szFileName)
{
int nWords = 0;//词计数变量,初始值为0
FILE *fp; //文件指针
char carrBuffer[1024];//每行字符缓冲,每行最多1024个字符
//打开文件
if ((fp = fopen(szFileName,  "r")) == NULL)
{
    return -1;  //文件打开不成功是返回-1
}
while (!feof(fp))//如果没有读到文件末尾 
{
    //从文件中读一行
    if (fgets(carrBuffer, sizeof(carrBuffer),fp) != NULL)
        //统计每行词数
        nWords += CountWordsInOneLine(carrBuffer);
}

//关闭文件
fclose(fp);
return nWords;
}
int CountWordsInOneLine(const char *szLine)
{
int nWords = 0;
int i=0;
for (;i<strlen(szLine);i++)
{
    if (*(szLine+i)!=‘ ‘)
    {
        nWords++;
        while ((*(szLine+i)!=‘ ‘)&&(*(szLine+i)!=‘‘))
        {
            i++;
        }
    }

}
        //printf("%d	",nWords);

return nWords;
}   

实验体会:

  • 课上时间能力不足,没能完成实验,课下参考了同学们的代码,自己还有很多不足。


以上是关于2018-2019-1 20165320 实验三 实时系统的主要内容,如果未能解决你的问题,请参考以下文章

20165320 Java实验三:敏捷开发与XP实践

2018-2019-1 20165320 《信息安全系统设计基础》第六周学习总结

2018-2019-1 20165320 《信息安全系统设计基础》第七周学习总结

2018-2019-1 20165320 《信息安全系统设计基础》第一周学习总结

2018-2019-1 20165320 《信息安全系统设计基础》第八周学习总结

20165320 第四次实验 Android开发