client、server端编程
首先是从main函数开发:
int main(itn argc,char* argv[])
{
pthread_t thread;
int count;
int status;
client_threads = CLIENT_THREADS;
for(count = 0;count <client_threads,count++)
{
status = pthread_create(&thread,NULL,client_routine,(void*)count);
if(status != 0)
err_abort(status,"Create client thread");
}
status = pthread_mutex_lock(&client_mutex);
if(status != 0)
err_abort(status,"Lock client mutex");
while(client_threads>0)
{
status = pthread_cond_wait(&clients_done,&client_mutex);
if(status != 0)
err_abort(status,"Wait for client to finish");
}
status = pthread_mutex_unlock(&client_mutex);
if(status != 0)
err_abort(status,"Unlock client mutex");
printf("All client done\n");
tty_server_request(REQ_QUIT,1,NULL,NULL);
return 0;
}
这个main函数在中间for循环中,调用pthread_create函数创建4个线程,传递给线程的数据位count(0,1,2,3).调用client_routine函数。
void *client_routine(void *arg)
{
int my_number = (int)arg,loops;
char prompt[32];
char string[128],formatted[128];
int status;
sprintf(prompt,"Client 5d>",my_number);
while(1)
{
tty_server_request(REQ_READ,1,prompt,string);
if(strlen(string) ==0)
break;
for(loops =0;loops <4;loops++)
{
sprintf(formatted,"(%d#%d)%s",my_number,loops,string);
tty_server_request(REQ_WRITE,0,NULL,formatted);
sleep(1);
}
}
status = pthread_mutex_lock(&client_mutex);
if(status != 0)
err_abort(status,"Lock client mutex");
client_threads--;
if(client_threads <= 0)
{
status = pthread_cond_signal(&clients_done);
if(status != 0)
err_abort(status,"Signale client done");
}
status = pthread_mutex_unlock(7client_mutex);
if(status != 0)
err_abort(status,"Unlock client mutex");
return NULL;
}
pthread_cond_wait() 必须与pthread_mutex
配套使用。pthread_cond_wait()函数一进入wait状态就会自己主动release mutex。当其它线程通过pthread_cond_signal()或pthread_cond_broadcast。把该线程唤醒,使pthread_cond_wait()通过(返回)时,该线程又自己主动获得该mutex。
在这里假设没有线程。则通知等待创建线程唤醒wait在此条件变量上的等待。
上面所有代码:
#include <pthread.h>
#include <math.h>
#include "errors.h"
#define CLIENT_THREADS 4
#define REQ_READ 1
#define REQ_WRITE 2
#define REQ_QUIT 3
typedef struct request_tag
{
struct request_tag *next;
int operation;
int synchronous;
int done_flag;
pthread_cond_t done;
char prompt[32];
char text[128];
}request_t;
typedef struct tty_server_tag
{
request_t *first;
request_t *last;
int running;
pthread_mutex_t mutex;
pthread_cond_t request;
}tty_server_t;
tty_server_t tty_server =
{
NULL,NULL,0,PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER
};
int client_threads;
pthread_mutex_t client_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t clients_done = PTHREAD_COND_INITIALIZER;
void *tty_server_routine(void *arg)
{
static pthread_mutex_t prompt_mutex = PTHREAD_MUTEX_INITIALIZER;
request_t *request;
int operation,len;
int status;
while(1)
{
status = pthread_mutex_lock(&tty_server.mutex);
if(status != 0)
err_abort(status,"Lock server mutex");
while(tty_server.first ==NULL)
{
status = pthread_cond_wait(&tty_server.request,&tty_server.mutex);
if(status != 0)
{
err_abort(status,"Wait for request");
}
request = tty_server.first;
tty_server.first= request->next;
if(tty_server.first == NULL)
{
tty_server.last = NULL;
}
status = pthread_mutex_unlock(&tty_server.mutex);
if(status != 0)
err_abrort(status,"Unlock server mutex");
operation = request->operation;
switch(operation)
{
case REQ_QUIT:
break;
case REQ_READ:
if(strlen(request->prompt)>0)
printf(request->prompt);
if(fgets(request->text,128,stdin)==NULL)
request->text[0]='\0';
len = strlen(request->text);
if(len>0&&request->text[len-1]=='\n')
request->text[len-1]='\0';
break;
case REQ_WRITE:
puts(request->text);
break;
default:
break;
}
if(request->synchronous)
{
status = pthread_mutex_lock(&tty_server.mutex);
if(status != 0)
err_abort(status,"Lock server mutex");
request->done_flag =1;
status = pthread_cond__signal(&request->done);
if(status != 0)
err_abort(status,"Unlock server mutex");
}else
free(request);
if(operation ==REQ_QUIT)
break;
}
return NULL;
}
void tty_server_request(int operation,int sync,const char* prompt,char* string)
{
request_t *request;
int status;
status =pthread_mutex_lock(&tty_server.mutex);
if(status != 0)
err_abort(status,"Lock server mutex");
if(!tty_server.running)
{
pthread_t thread;
pthread_attr_t detached_attr;
status = pthread_attr_init(&detached_attr);
if(status != 0)
err_abort(status,"Init attributes object");
status = pthread_attr_setdetachstate(&detached_attr,PTHREAD_CREATE_DETACHED);
if(status != 0)
err_abort(status,"Set detach state");
tty_server.running = 1;
status = pthread_create(&thread,&detached_attr,tty_server_routine,NULL);
if(status != 0)
err_abort(status,"Create server");
pthread_attr_destroy(&detached_attr);
}
request = (request_t*)malloc(sizeof(request_t));
if(request ==NULL)
errno_abort("Allocate Request");
request->next = NULL;
request->operation = operation;
request->synchronous = sync;
if(sync)
{
request->done_flag = 0;
status = pthread_cond_init(&request->done,NULL);
if(status != 0)
err_abort(status ,"Init request condition");
}
if(prompt != NULL)
strncpy(request->prompt,prompt,32);
else
request->prompt[0]='\0';
if(operation == REQ_WRITE &&string != NULL)
strncpy(request->text,string,128);
else
request->text[0]='\0';
if(tty_server.first == NULL)
{
tty_server.first = request;
tty_server.last = request;
}else
{
(tty_server.last)->next = request;
tty_server.last= request;
}
status = pthread_cond_signal(&tty_server.request);
if(status != 0)
err_abort(status,"Wake server");
if(sync)
{
while(!request->done_flag)
{
status = pthread_cond_wait(&request->done,&tty_server.mutex);
if(status != 0)
err_abort(status,"Wait for sync request");
}
if(operation == REQ_READ)
{
if(strlen(request->text)>0)
strcpy(string,request->text);
else
string[0]='\0';
}
status = pthread_cond_destroy(&request->done);
if(status != 0)
err_abort(status,"destroy request condition");
free(request);
}
status = pthread_mutex_unlock(&tty-server.mutex);
if(status != 0)
err_abort(status,"Unlock mutex");
}
client、server端编程的更多相关文章
- Python的XMLRPC机制:实现跨进程间、client/server端通信
SimpleXMLRPCServer模块式python语言的一个基于 xml 格式的进程间通信的基础框架. SimpleXMLRPCServer是一个单线程的服务器,这意味着,如果几个客户端同时发出多 ...
- client / server端用户的登录
# 客户端 import socket import hashlib import json import os import struct sk = socket.socket() # 实例化 sk ...
- Linux下的C Socket编程 -- server端的继续研究
Linux下的C Socket编程(四) 延长server的生命周期 在前面的一个个例子中,server在处理完一个连接后便会立即结束掉自己,然而这种server并不科学啊,server应该是能够一直 ...
- Linux下的C Socket编程 -- server端的简单示例
Linux下的C Socket编程(三) server端的简单示例 经过前面的client端的学习,我们已经知道了如何创建socket,所以接下来就是去绑定他到具体的一个端口上面去. 绑定socket ...
- UDP也需要现有Server端,然后再有Client端
UDP编程: DatagramSocket(邮递员):对应数据报的Socket概念,不需要创建两个socket,不可使用输入输出流. DatagramPacket(信件):数据包,是UDP下进行传输数 ...
- HBase 协处理器编程详解第一部分:Server 端代码编写
Hbase 协处理器 Coprocessor 简介 HBase 是一款基于 Hadoop 的 key-value 数据库,它提供了对 HDFS 上数据的高效随机读写服务,完美地填补了 Hadoop M ...
- Socket编程, 在server端read()函数调用后显示错误:Transport endpoint is not connected (犯了低级错误)
for(;;){ socklen_t len = sizeof(client_address); connfd = accept(listenfd, (struct sockaddr *)&c ...
- 从零开始学习Node.js例子四 多页面实现数学运算 续二(client端和server端)
1.server端 支持数学运算的服务器,服务器的返回结果用json对象表示. math-server.js //通过监听3000端口使其作为Math Wizard的后台程序 var math = r ...
- 应用java多线程实现server端与多client之间的通信
应用多线程来实现server与多线程之间的通信的基本步骤 1.server端创建ServerSocket,循环调用accept()等待client链接 2.client创建一个Socket并请求和se ...
随机推荐
- centos6.5下 python3.6安装、python3.6虚拟环境
https://www.cnblogs.com/paladinzxl/p/6919049.html # python3.6的安装 wget https://www.python.org/ftp/pyt ...
- UVA - 10674-Tangents
题意:给出两个圆,求它们的公切线,并依照一定格式输出 做法:模拟 代码: #include<iostream> #include<map> #include<str ...
- XMPP开发之从零開始
对于server的搭建和设置.我在这里就不再多说了.有好多前辈已经帮大家攻克了.能够參考下这篇博客 XMPPserver配置 我依照这个博客配置好了,server后,然后在网上參照代码写了一个小的de ...
- SDUT--Pots(二维BFS)
Pots Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描写叙述 You are given two pots, having the ...
- shell-手机屏幕录制
今天在做android联系的时候,想要把自己写的demo效果记录下来.在网上发现了录制手机屏幕的方法,如下 adb shell screenrecord /sdcard/demo.mp4 解释 adb ...
- ContentValues的使用
什么是 ContentValues类? ContentValues类和 Hashtable比较类似,它也是负责存储一些名值对,但是它存储的名值对当中的名是一个String类型,而值都是基本类型. 插入 ...
- HDU 4631 Sad Love Story 平面内最近点对
http://acm.hdu.edu.cn/showproblem.php?pid=4631 题意: 在平面内依次加点,求每次加点后最近点对距离平方的和 因为是找平面最近点对...所以加点以后这个最短 ...
- 洛谷 P1109 学生分组
P1109 学生分组 题目描述 有N组学生,给出初始时每组中的学生个数,再给出每组学生人数的上界R和下界L(L<=R),每次你可以在某组中选出一个学生把他安排到另外一组中,问最少要多少次才可以使 ...
- 多线程中的"断点"续传《notify()和wait()》
眼下在做一个项目.关于软件管理与下载的,预计项目提交日期定在6月9号.项目做了有20天了,可是在一个功能上卡住了.在这个项目中有一个功能----APK的下载须要实现. 相信大家都玩过非常多关于下载AP ...
- Android应用开发-广播和服务
广播 广播的概念 现实:电台通过发送广播发布消息,买个收音机,就能收听 Android:系统在产生某个事件时发送广播,应用程序使用广播接收者接收这个广播,就知道系统产生了什么事件. Android系统 ...