2019-2020-1 20175304 20175303 20175327 20175335 实验三-并发程序
Posted cxd20175303
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019-2020-1 20175304 20175303 20175327 20175335 实验三-并发程序相关的知识,希望对你有一定的参考价值。
2019-2020-1 20175304 20175303 20175327 20175335 实验三-并发程序
实验过程
实验三-并发程序-1
实验要求
学习使用Linux命令wc(1)
基于Linux Socket程序设计实现wc(1)服务器(端口号是你学号的后6位)和客户端
客户端传一个文本文件给服务器
服务器返加文本文件中的单词数
上方提交代码
附件提交测试截图,至少要测试附件中的两个文件
实验步骤
首先先学习一下命令wc使用
1.在命令行输入 man wc
2.使用方法
3.部分实例
(1)统计行数 $wc –l file
(2)统计单词数 $wc –w file
(3)统计字符数 $wc –c file
(4)统计流中的字符数 $echo –n 1234 | wc –c
基于Linux Socket程序设计实现wc
Sever端代码:
#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
#include<unistd.h>
#define SERVER_PORT 175303
#define LENGTH_OF_LISTEN_QUEUE 20
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512
int CountWordsOfEuropeanTxtFile(char *szFileName);
int CountWordsInOneLine(const char *szLine);
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("5303:%s
", file_name);
int count=0;
bzero(buffer, BUFFER_SIZE);
count = CountWordsOfEuropeanTxtFile(file_name);
sprintf(buffer,"%d", count);
if(send(new_server_socket_fd, buffer, sizeof(buffer), 0) < 0)
{
printf("Send File:%s Failed./n", file_name);
}
bzero(buffer, BUFFER_SIZE);
/*/ 打开文件并读取文件数据
FILE *fp = fopen(file_name, "r");
if(NULL == fp)
{
printf("File:%s Not Found
", file_name);
}
else
{
bzero(buffer, BUFFER_SIZE);
int length = 0;
/ 每读取一段数据,便将其发送给客户端,循环直到文件读完为止
while((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
{
if(send(new_server_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!
", file_name);
}*/
// 关闭与客户端的连接
close(new_server_socket_fd);
}
// 关闭监听用的socket
close(server_socket_fd);
return 0;
}
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)!='