博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2018-2019-1 20165303 实验三 实时系统
阅读量:6040 次
发布时间:2019-06-20

本文共 9998 字,大约阅读时间需要 33 分钟。

实验三-并发程序-1

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

上方提交代码

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

  • 命令参数:

    -c 统计字节数。
    -l 统计行数。
    -m 统计字符数。这个标志不能与 -c 标志一起使用。
    -w 统计字数。一个字被定义为由空白、跳格或换行字符分隔的字符串。
    -L 打印最长行的长度。
    -help 显示帮助信息
    --version 显示版本信息

  • server

    ´´´

    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 155306

define BACKLOG 1

define MAXRECVLEN 1024

int main(int argc, char argv[])

{
char buf[MAXRECVLEN];
int listenfd, connectfd; /
socket descriptors /
struct sockaddr_in server; /
server's address information /
struct sockaddr_in client; /
client's address information /
socklen_t addrlen;
/
Create TCP socket /
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
/
handle exception */
perror("socket() error. Failed to initiate a socket");
exit(1);
}

/* set socket option */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){    /* handle exception */    perror("Bind() error.");    exit(1);}if(listen(listenfd, BACKLOG) == -1){    perror("listen() error. \n");    exit(1);}addrlen = sizeof(client);while(1){    if((connectfd=accept(listenfd,(struct sockaddr *)&client, &addrlen))==-1)      {        perror("accept() error. \n");        exit(1);      }    FILE *stream;    struct timeval tv;    gettimeofday(&tv, NULL);      printf(" Client ip :  %s \n",inet_ntoa(client.sin_addr));  printf(" Port id : %d \n ",htons(client.sin_port));  printf("Time is %ld.%ld\n",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,"Word number:");

strcat(buf,"Word number:");

char s[21];
long int count = 0;
while(fscanf(stream,"%s",s)!=EOF)
count++;
char str[10];
sprintf(str, " %ld\n", count);
int n = sizeof(str);
str[n] = '\0';
strcat(buf,"\n");

//strcat(buf,"\t");strcat(buf,str);

printf("\n");

strcat(buf,"\n");

}else        {            close(connectfd);            break;        }        /* print client's ip and port */        send(connectfd, buf, iret, 0); /* send to the client welcome message */    }close(listenfd); /* close listenfd */return 0;

}

´´´

  • client

    ´´´

    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> /* netdb is necessary for struct hostent */

define PORT 155306 /* server port */

define MAXDATASIZE 100

int main(int argc, char argv[])

{
int sockfd, num; /
files descriptors /
char buf[MAXDATASIZE]; /
buf will store received text /
struct hostent
he; /* structure that will get information about remote host */
struct sockaddr_in server;

if (argc != 3){    printf("Usage: %s 
\n",argv[0]); exit(1);}if((he=gethostbyname(argv[1]))==NULL){ printf("gethostbyname() error\n"); exit(1);}if((sockfd=socket(AF_INET,SOCK_STREAM, 0))==-1){ printf("socket() error\n"); 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\n"); exit(1);}

char str[MAXDATASIZE] ;

strcpy(str,argv[2]);

if((num=send(sockfd,str,sizeof(str),0))==-1){

printf("send() error\n");
exit(1);
}
if((num=recv(sockfd,buf,MAXDATASIZE,0))==-1)
{
printf("recv() error\n");
exit(1);
}
buf[num-1]='\0';
printf(" Successful! \n %s\n",buf);

close(sockfd);return 0;

}

´´´

1296850-20181118122715348-660683109.png

实验三-并发程序-2

使用多线程实现wc服务器并使用同步互斥机制保证计数正确

上方提交代码
下方提交测试
对比单线程版本的性能,并分析原因

  • server

    ´´´

    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!\n");
    exit(1);
    }
    fd_temp = listen(sockfd_server,MAX_CONN_LIMIT);
    if(fd_temp == -1)
    {
    fprintf(stderr,"listen error!\n");
    exit(1);
    }
    while(1)
    {
    printf("waiting for new connection...\n");
    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!\n");
    continue; //ignore current socket ,continue while loop.
    }
    printf("A new connection occurs!\n");
    if(pthread_create(&thread_id,NULL,(void
    )(&Data_handle),(void )(&sockfd)) == -1)
    {
    fprintf(stderr,"pthread_create error!\n");
    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\n");
    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!\n";
    while(1)
    {
    printf("waiting for file_name...\n");
    //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\n");
    break;
    }
    if(i_recvBytes == -1)
    {
    fprintf(stderr,"read error!\n");
    break;
    }
    if(strcmp(data_recv,"quit")==0)
    {
    printf("Quit command!\n");
    break; //Break the while loop.
    }
    printf("read from client : %s\n",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...\n");
    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)!='\0'))
    {
    i++;
    }
    }

    }

    //printf("%d\t",nWords);

    return nWords;

    }
    ´´´

  • client

    ´´´

    include<stdlib.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

    int main()

    {
    int sockfd;
    int tempfd;
    struct sockaddr_in s_addr_in;
    char data_send[BUFFER_LENGTH];
    char data_recv[BUFFER_LENGTH];
    memset(data_send,0,BUFFER_LENGTH);
    memset(data_recv,0,BUFFER_LENGTH);
    sockfd = socket(AF_INET,SOCK_STREAM,0); //ipv4,TCP
    if(sockfd == -1)
    {
    fprintf(stderr,"socket error!\n");
    exit(1);
    }
    //before func connect, set the attr of structure sockaddr.
    memset(&s_addr_in,0,sizeof(s_addr_in));
    s_addr_in.sin_addr.s_addr = inet_addr("127.0.0.1"); //trans char * to in_addr_t
    s_addr_in.sin_family = AF_INET;
    s_addr_in.sin_port = htons(SOCK_PORT);
    tempfd = connect(sockfd,(struct sockaddr *)(&s_addr_in),sizeof(s_addr_in));
    if(tempfd == -1)
    {
    fprintf(stderr,"Connect error! \n");
    exit(1);
    }
    while(1)
    {
    printf("Please Input File Name On Server(input "quit" to quit):\t");
    scanf("%s", data_send);
    //gets(data_send);
    //scanf("%[^\n]",data_send); //or you can also use this
    tempfd = write(sockfd,data_send,BUFFER_LENGTH);
    if(tempfd == -1)
    {
    fprintf(stderr,"write error\n");
    exit(0);
    }

    if(strcmp(data_send,"quit") == 0)  //quit,write the quit request and shutdown client  {      break;  }  else  {      tempfd = read(sockfd,data_recv,BUFFER_LENGTH);      assert(tempfd != -1);      printf("%s\n",data_recv);      memset(data_send,0,BUFFER_LENGTH);      memset(data_recv,0,BUFFER_LENGTH);  }
    char buffer[BUFFER_LENGTH];
    int length=0;
    bzero(buffer, BUFFER_LENGTH);
    length = recv(sockfd, buffer, BUFFER_LENGTH, 0);
    buffer[length] = '\0';
    printf("count=%s\n", buffer);
    bzero(buffer, BUFFER_LENGTH);
    }
    int ret = shutdown(sockfd,SHUT_WR); //or you can use func close()--<unistd.h> to close the fd
    assert(ret != -1);
    return 0;
    }
    ´´´
    1296850-20181118122944729-1155032913.png
  • 多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。

转载于:https://www.cnblogs.com/Vventador/p/9977520.html

你可能感兴趣的文章
使用gitbook editor管理个人笔记/制作PDF电子书
查看>>
《Kotlin 极简教程》第15章 Kotlin 文件IO操作与多线程
查看>>
Windows中常见进程详解
查看>>
apl脚本入门-变量
查看>>
从Oracle迁移到MySQL的各种坑及自救方案
查看>>
巧用group by替代 distinct【记录一次sql之旅】
查看>>
linux下xxd以16进制显示二进制文件内容
查看>>
@Transactional 类事务说明机制
查看>>
python命名规则
查看>>
没事无聊写S2H玩,遇到乱码问题。。。
查看>>
Spring MVC JAR 包
查看>>
CentOS 7 安装NFS服务端和客户端
查看>>
Linux 修改 yum 本地源
查看>>
spring DataSourceUtils
查看>>
Elasticsearch使用REST API实现全文检索
查看>>
Kafka Consumer端的一些解惑
查看>>
Elasticsearch JDBC的使用-MySQL 数据源导入和增量索引、更新
查看>>
Windows 8.1时代,不需要卫士软件
查看>>
Confluence 6 找到未使用的空间
查看>>
系统集成资质培训 - 成本管理考前冲刺题目练习
查看>>