Linux下使用多线程模拟异步网络通信
服务器
/* socket server
* 2014-12-15 CopyRight (c) arbboter
*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <vector>
using namespace std; vector<int> vecClient;
// 线程同步锁
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; void* recv_thr(void*p);
void* send_thr(void*p);
int main()
{
int sockfd_server;
int sockfd_client;
struct sockaddr_in addr_server;
struct sockaddr_in addr_client;
socklen_t addr_len = ;
int client_max = ;
int server_port = ; srand(time(NULL)); // create socket
sockfd_server = socket(AF_INET, SOCK_STREAM, );
if(sockfd_server == -)
{
printf("init socket failed\n");
return -;
} // set address
memset(&addr_server, , sizeof(addr_server));
addr_server.sin_family = AF_INET;
addr_server.sin_addr.s_addr = htonl(INADDR_ANY);
addr_server.sin_port = htons(server_port); // socket bind with address
if(bind(sockfd_server, (struct sockaddr*)&addr_server, sizeof(struct sockaddr)) == -)
{
printf("bind socket failed\n");
return -;
} // server socket start list, waitting client to connect
// 这个client_max是指同时连接数
if(listen(sockfd_server, client_max) == -)
{
printf("start listen socket failed\n");
return -;
} // 数据线程
pthread_t tid = ; pthread_create(&tid, NULL, send_thr, NULL);
while()
{
addr_len = sizeof(struct sockaddr_in);
printf("waitting for connected...\n"); // waitting for connected
sockfd_client = accept(sockfd_server, (struct sockaddr*)&addr_client, &addr_len);
if(sockfd_client == -)
{
printf("accept socket failed\n");
return -;
} // create a thread to talk with client
printf("recived connection from : %s\n", inet_ntoa(addr_client.sin_addr));
pthread_create(&tid, NULL, recv_thr, (void*)&sockfd_client); // 加到发数据对象集合中
pthread_mutex_lock(&mutex);
vecClient.push_back(sockfd_client);
pthread_mutex_unlock(&mutex);
}
close(sockfd_server);
pthread_mutex_destroy(&mutex);
return ;
} // 收数据
void* recv_thr(void*p)
{
int fd = *((int*)p);
int nRead = ;
char szBuf[] = {}; while()
{
memset(szBuf, , sizeof(szBuf));
nRead = read(fd, szBuf, sizeof(szBuf));
printf("client : %s\n", szBuf); if(strcmp(szBuf, "quit") == )
{
break;
} sprintf(szBuf, "Your magic number is : %d", rand()%);
printf("server : %s\n", szBuf);
write(fd, szBuf, strlen(szBuf));
}
return NULL;
} // 发数据
void* send_thr(void*p)
{
size_t i = ;
char szBuf[] = {}; while()
{
sleep(rand()%);
pthread_mutex_lock(&mutex);
for(int i=; i<vecClient.size(); i++)
{
sprintf(szBuf, "Your magic number is : %d", rand()%);
printf("[%02d] server : %s\n", i, szBuf);
write(vecClient[i], szBuf, strlen(szBuf));
}
pthread_mutex_unlock(&mutex);
}
return NULL;
}
客户端
/* socket client
* 2014-12-15 CopyRight (c) arbboter
*/
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <signal.h>
#include <errno.h>
#include <string.h> void* recv_thr(void*p);
int main()
{
int sockfd_server;
struct sockaddr_in addr_server;
socklen_t addr_len = ;
int server_port = ;
char* server_addr = "192.168.2.200"; // create socket
sockfd_server = socket(AF_INET, SOCK_STREAM, );
if(sockfd_server == -)
{
printf("init socket failed\n");
return -;
} // set server address
memset(&addr_server, , sizeof(addr_server));
addr_server.sin_family = AF_INET;
addr_server.sin_addr.s_addr = inet_addr(server_addr);;
addr_server.sin_port = htons(server_port); // connect server
if(connect(sockfd_server,(struct sockaddr *)&addr_server,sizeof(struct sockaddr))==-)
{
printf("connect server failed\n");
return -;
} // 启动收数据线程
pthread_t tid = ;
pthread_create(&tid, NULL, recv_thr, (void*)&sockfd_server); // 发送数据
char szBuf[] = {};
int nLen = ;
while()
{
// 收线程已退出
if( ESRCH == pthread_kill(tid,) )
{
break;
}
// 等待输入数据
gets(szBuf);
nLen = strlen(szBuf);
if(nLen > )
{
szBuf[nLen] = '\0';
write(sockfd_server, szBuf, nLen);
}
}
close(sockfd_server);
return ;
} // 收数据
void* recv_thr(void*p)
{
int fd = *((int*)p);
int nRead = ;
char szBuf[] = {}; while()
{
memset(szBuf, , sizeof(szBuf));
nRead = read(fd, szBuf, sizeof(szBuf));
printf("server : %s\n", szBuf); if(strcmp(szBuf, "quit") == )
{
break;
}
}
return NULL;
}
Linux下使用多线程模拟异步网络通信的更多相关文章
- 【转】 Linux下的多线程编程
作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/原文链接:http://www.cnblogs.com/gnuhpc/archive/2012/12/07/280 ...
- Linux下的多线程编程
1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的 Unix也支持线程的概念,但是在一个进程(proces ...
- 【转】Linux下的多线程编程
1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的 Unix也支持线程的概念,但是在一个进程(proces ...
- 《转》Linux下的多线程编程
原地址:http://linux.chinaunix.net/doc/program/2001-08-11/642.shtml 1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程 ...
- linux下php pcntl_fork模拟多线程
开始用php写后台服务一段时间了.也是在这样的驱动下,不断的学习php语法,体验这一原来一直以为神秘且敬而远之的神奇语言的魅力.最初看php多线程的资料是为了提高程序的处理能力,充分发挥linux多任 ...
- Linux下基于多线程的echo
准备开始写一些Linux 下网络编程以及多线程的blog,就从这个简单的echo程序开始吧. 在echo的服务端使用多线程与客户进行通信,可以实现一个服务端程序同时连接多个客户的功能.那么,到底在服务 ...
- linux下的多线程,pthread_create函数
pthread_create是UNIX环境创建线程函数 头文件 #include<pthread.h> 函数声明 int pthread_create(pthread_t*restrict ...
- 【转】Linux下的多线程编程背景知识
1. 进程和线程 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的 Unix也支持线程的概念,但是在一个进程(pr ...
- linux下使用多线程编写的聊天室
自从开始学linux网络编程后就想写个聊天室,一开始原本打算用多进程的方式来写,可是发觉进程间的通信有点麻烦,而且开销也大,后来想用多线程能不能实现呢,于是便去看了一下linux里线程的用法,实际上只 ...
随机推荐
- hibernate像MySQL数据库里面存值是中文乱码的解决合辑
解决办法一: 1.把数据库表每一行改成gb2312_chinese(使用PHPMyAdmin) 2.导入时候还是不行,因此查网上的资料说hibernate持久化层在传输过程中未设置编码格式,这样在 ...
- 用jQuery与JSONP轻松解决跨域访问的问题【转】
原文地址:http://www.jb51.net/article/46463.htm 好在,有jquery帮忙,跨域问题似乎没那么难缠了.这次也借此机会对跨域问题来给刨根问底,结合实际的开发项目,查阅 ...
- sass基础学习
2015.6.281.安装ruby2.运行gem安装sass-->gem install sass3.编译命令行sass --watch 文件路径/test.scss:编译后文件路径/test. ...
- POJ2002 二分查找&哈希
问题重述: 给定整数n,以及n个点的坐标xi, yi.求这n个点可以组成的正方形的数目(每个点可重复使用). 分析: 根据正方形的性质,给定两个点就能确定可能构成的两个正方形的另外两个顶点.因此,只需 ...
- windows下安装phpcms html/ 文件夹不可写的一种错误以及解决方法
朋友安装phpcms时遇到奇葩问题,环境搭建在windows7中,竟然出现 html/ 和 phpsso_server/caches/文件夹不可写问题(如图) 在windows下出现这种权限的问题真不 ...
- SQL如何查询两个表的数据
在进行查询操作时,我们通常需要查询两个关联表的数据,我们可以使用where语句进行查询,如: select Emp.E_Id,Company.C_OraName from Emp,Company wh ...
- Swift—属性观察者-备
为了监听属性的变化,Swift提供了属性观察者.属性观察者能够监听存储属性的变化,即便变化前后的值相同,它们也能监听到. 属性观察者主要有以下两个: willSet:观察者在修改之前调用. didSe ...
- SVN莫名出错,网上找遍无果,递归删除当前目录下所有.svn文件名
哎,太深刻的教训. 原来以前其它目录里有.SVN目录 ,而此SVN目录COPY到真正的SVN工作目录之后,会将有用的.SVN目录覆盖. 那么一样,显然,CI,UPDATE,CO之间的命令全部异常... ...
- BZOJ 2527 Meteors
http://www.lydsy.com/JudgeOnline/problem.php?id=2527 思路:整体二分 #include<cstdio> #include<cmat ...
- KEIL中的变量相关
例:sfr P0=0x80表示P0口地址为80H:(sfr是字节操作) sfr16 T2=0xCC表示T2口地址的低地址为TL2=0XCC,高地址为TH2=0XCD(sfr16是字操作) 头文件reg ...