标签:同步 空格 字符 scanf 接口 参数说明 技术 关闭 types
利用wc命令统计文档text1.txt和text2.txt的字数,并且作为接下来实验正确性的判断标准
客户端:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
#pragma comment(lib,"ws2_32.lib")
#define MY_PORT 165310
#define DEST_IP "172.20.10.4"
int main()
{
SOCKET con_socket;
struct sockaddr_in remote_addr;
char buffer[1024];
char file_name[100];
char readch;
int i;
WSADATA wsaDate;
WSAStartup(MAKEWORD(1,1),&wsaDate);
memset(file_name,0,sizeof(file_name));
memset(buffer,0,sizeof(buffer));
remote_addr.sin_family=AF_INET;
remote_addr.sin_port=htons(MY_PORT);
remote_addr.sin_addr.s_addr=inet_addr(DEST_IP);
con_socket=socket(AF_INET,SOCK_STREAM,0);
if(con_socket==-1)
{
printf("Client socket failed!");
exit(0);
}
printf("Please Input File Name:\n");
scanf("%s", file_name);
if(connect(con_socket,(struct sockaddr*)&remote_addr,sizeof(struct sockaddr))==-1)
{
printf("Client connet failed!");
}
else
{
FILE *fp=fopen(file_name,"r");
if(fp==NULL)
{
printf("%s File not Found!\n",file_name);
}
else
{
while((readch=fgetc(fp))!=EOF)
{
if(i<1024)
{
buffer[i]=readch;
i++;
}
else
{
i=0;
int n=send(con_socket, buffer, 1024, 0);
if(n==-1)
{
printf("Send File Error!\n");
}
}
}
fclose(fp);
printf("File:%s Transfer Finished!\n", file_name);
}
fclose(fp);
long wordscount;
recv(con_socket, &wordscount, sizeof(long), 0);
printf("%ld\n", wordscount);
}
closesocket(con_socket);
WSACleanup();
return 0;
}
?
服务器:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#define MYPORT 165310
void main()
{
int server_socket, client_socket;
struct sockaddr_in my_addr;
struct sockaddr_in remote_addr;
char buffer[BUFSIZ];
memset(&my_addr, 0, sizeof(my_addr));
my_addr.sin_family=AF_INET;
my_addr.sin_addr.s_addr=INADDR_ANY;
my_addr.sin_port=htons(MYPORT);
if((server_socket=socket(PF_INET, SOCK_STREAM, 0))==-1)
{
perror("socket");
}
if(bind(server_socket, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))<0)
{
perror("bind");
}
listen(server_socket, 5);
int addrlen=sizeof(struct sockaddr_in);
while(1)
{
if((client_socket
=accept(server_socket, (struct sockaddr *)&remote_addr, &addrlen))<0)
{
perror("accept");
}
printf("accept client %s\n", inet_ntoa(remote_addr.sin_addr));
int len, i;
long wordscount=0;
int flag=1;
while(1)
{
if((len=recv(client_socket, buffer, 1024, 0))>0)
{
for(i=0; i<len; i++)
{
if(flag==0)
{
switch(buffer[i])
{
case ‘ ‘:
wordscount++;
break;
case ‘\n‘:
wordscount++;
break;
case ‘\r‘:
wordscount++;
break;
default:
break;
}
}
if(buffer[i]== ‘ ‘ || buffer[i]==‘\n‘ || buffer[i]==‘\r‘) flag=1;
else flag=0;
}
}
if(len<1024) break;
}
send(client_socket, &wordscount, sizeof(long), 0);
close(client_socket);
}
close(server_socket);
}
?
使用多线程实现wc服务器并使用同步互斥机制保证计数正确
客户端:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
#pragma comment(lib,"ws2_32.lib")
#define MY_PORT 165310
#define DEST_IP "172.20.10.4"
int main()
{
SOCKET con_socket;
struct sockaddr_in remote_addr;
char buffer[1024];
char file_name[100];
char readch;
int i;
WSADATA wsaDate;
WSAStartup(MAKEWORD(1,1),&wsaDate);
memset(file_name,0,sizeof(file_name));
memset(buffer,0,sizeof(buffer));
remote_addr.sin_family=AF_INET;
remote_addr.sin_port=htons(MY_PORT);
remote_addr.sin_addr.s_addr=inet_addr(DEST_IP);
con_socket=socket(AF_INET,SOCK_STREAM,0);
if(con_socket==-1)
{
printf("Client socket failed!");
exit(0);
}
printf("Please Input File Name:\n");
scanf("%s", file_name);
if(connect(con_socket,(struct sockaddr*)&remote_addr,sizeof(struct sockaddr))==-1)
{
printf("Client connet failed!");
}
else
{
FILE *fp=fopen(file_name,"r");
if(fp==NULL)
{
printf("%s File not Found!\n",file_name);
}
else
{
while((readch=fgetc(fp))!=EOF)
{
if(i<1024)
{
buffer[i]=readch;
i++;
}
else
{
i=0;
int n=send(con_socket, buffer, 1024, 0);
if(n==-1)
{
printf("Send File Error!\n");
}
}
}
fclose(fp);
printf("File:%s Transfer Finished!\n", file_name);
}
fclose(fp);
long wordscount;
recv(con_socket, &wordscount, sizeof(long), 0);
printf("%ld\n", wordscount);
}
closesocket(con_socket);
WSACleanup();
return 0;
}
?
服务器:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <pthread.h>
#pragma comment(lib,"ws2_32.lib")
pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
#define MY_PORT 165310
typedef struct socket_counter
{
SOCKET send_socket;
char buffer[1024];
}socket_counter;
void my_wc(socket_counter *my_counter);
int main()
{
SOCKET listen_socket;//声明Socket接口变量
struct sockaddr_in my_addr;//声明Socket地址变量
int dummy,rev_length;
//char buffer[1024];
char file_name[100];
pthread_t t;
socket_counter *my_counter;
WSADATA wsaDate;
WSAStartup(MAKEWORD(1,1),&wsaDate);//启动版本
listen_socket=socket(AF_INET,SOCK_STREAM,0);//声明为IPV4的TCP
my_addr.sin_family=AF_INET;//IPV4
my_addr.sin_port=htons(MY_PORT);//端口
my_addr.sin_addr.s_addr=htonl(INADDR_ANY);//可以连接任一电脑
dummy = sizeof(SOCKADDR);
memset(file_name,0,sizeof(file_name));
if( bind(listen_socket,(struct sockaddr*)&my_addr,sizeof(struct sockaddr))<0)//绑定本地IP与Socket
{
printf("Server Bind error!\n");
}
if(listen(listen_socket,5)<0)//等待序列,默认队列最多为5个请求
{
printf("Server Listen error!\n");
}
while(1)
{
my_counter->send_socket=accept(listen_socket,NULL,&dummy);//listen函数创建等待队列后,accept函数处理客户端发来的连接请求
if(my_counter->send_socket==-1)
{
printf("Server Accept failed!\n");
break;
}
printf("Accept success!\n");
pthread_create(&t, NULL, &my_wc,my_counter);
pthread_join(&t, NULL);
}
closesocket(listen_socket);//依次关闭连接
WSACleanup();//清除
return 0;
}
void my_wc(socket_counter *my_counter){
pthread_mutex_lock( &counter_mutex );
int len, i;
long wordscount=0;
int flag=1;
while(1)
{
if((len=recv(my_counter->send_socket, my_counter->buffer, 1024, 0))>0)
{
for(i=0; i<len; i++)
{
if(flag==0)
{
switch(my_counter->buffer[i])
{
case ‘ ‘:
wordscount++;
break;
case ‘\n‘:
wordscount++;
break;
case ‘\r‘:
wordscount++;
break;
default:
break;
}
}
if(my_counter->buffer[i]== ‘ ‘ || my_counter->buffer[i]==‘\n‘ || my_counter->buffer[i]==‘\r‘)
flag=1;
else
flag=0;
}
}
if(len<1024) break;
}
send(my_counter->send_socket, &wordscount, sizeof(long), 0);
close(my_counter->send_socket);
pthread_mutex_unlock( &counter_mutex );
}
?
多线程变量声明:pthread_t <变量名>
创建线程的函数pthread_create
:
? 函数声明:int pthread_create(pthread_t *tidp,const
pthread_attr_t *attr,(void*)(*start_rtn)(void*),void *arg);
? 函数说明:类Unix操作系统(Unix、Linux、Mac OS X等)的创建线程的函数。它的功能是创建线程(实际上就是确定调用该线程函数的入口点),在线程创建以后,就开始运行相关的线程函数。表示成功,返回0;表示出错,返回表示-1。
? 参数说明:第一个参数为指向线程标识符的指针。第二个参数用来设置线程属性。第三个参数是线程运行函数的起始地址。最后一个参数是运行函数的参数。
线程回收函数pthread_join
:
? 函数声明:int pthread_join(pthread_t thread, void **retval);
? 函数说明:以阻塞的方式等待thread指定的线程结束。当函数返回时,被等待线程的资源被收回。如果线程已经结束,那么该函数会立即返回。 0代表成功。 失败,返回的则是错误号。
? 参数说明:第一个参数为线程标识符,即线程ID,标识唯一线程。第二个参数为 用户定义的指针,用来存储被等待线程的返回值。
互斥锁函数pthread_mutex_lock
:
? 函数声明:int pthread_mutex_lock(pthread_mutex_t *mutex);
? 函数说明:线程调用该函数让互斥锁上锁,如果该互斥锁已被另一个线程锁定和拥有,则调用该线程将阻塞,直到该互斥锁变为可用为止。 成功完成之后会返回零。其他任何返回值都表示出现了错误。
pthread_create
函数传参只能传一个值,然而程序中需要传入两个值
解决方法:利用C语言结构体,传入结构体作为唯一参数
计算出单词个数不正确,少于正确值
解决方法:只计算了空格,没有计算‘\n‘、‘\r‘等特殊字符
标签:同步 空格 字符 scanf 接口 参数说明 技术 关闭 types
原文地址:https://www.cnblogs.com/atbaoi/p/9977653.html