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里线程的用法,实际上只 ...
随机推荐
- ECSTORE1.2 重启开启信任登陆模块(删除KEY)
1).若启用Mongodb 需要删除KEY分别为 1 2 3 be90a668d9f2eb1950bae1bf6b0835ce 939e64939c3f65cfb646e7948c5b80df 58d ...
- php 中_set()_get()实例解析
<?php class Person { // 下面是人的成员属性, 都是封装的私有成员 private $name; // 人的名子 private $sex; // 人的性别 private ...
- 创建C#DLL
1. 创建classlibrary 2.编写一个COM接口和一个COM类 [Guid("DBE0E8C4-1C61-41f3-B6A4-4E2F353D3D05")] public ...
- 钢管下料问题2(剩余材料最少)lingo求解
大家好,我是小鸭酱,博客地址为:http://www.cnblogs.com/xiaoyajiang !钢管下料问题2(剩余材料最少) 题目: 钢管原料 每根19m 客户需求 4m 50根 ...
- VIM下Express jade空格问题:expected "indent", but got "newline"
Error: /home/y/my_note/nodejs/myapp/views/index.jade: | -list=[{name:,email:'zhangsan@123.com'}] | - ...
- 技巧两种:LINUX删除指定后缀文件及PYTHON更改屏幕字色
http://blog.csdn.net/caryaliu/article/details/8753028 http://www.iitshare.com/python-print-color-log ...
- Powershell Switch 条件
Powershell Switch 条件 6 21 1月, 2012 在 Powershell tagged Powershell教程/ 分支/ 字符串/ 数字/ 条件by Mooser Lee 本 ...
- 【转】Windows 7/8/8.1 硬盘安装法实现 ubuntu 14.04 双系统
原文网址:http://www.cnblogs.com/chenguangqiao/p/4219532.html 一.软件准备 1. 下载 Ubuntu 系统镜像:http://www.ubuntu. ...
- MVC4.0系统开发新手历程(四)数据列表查询
任何系统都不可避免的就是数据的查询展示,我觉得这里最值得一说的就是分部视图以及数据分页了 首先添加控制器 在控制其上面的名字为Index的Action上面右击,添加视图即可添加对应的视图,分部视图呈现 ...
- STL中,back_insert_iterator与back_inserter的区别。
1.参考http://www.cplusplus.com网站关于back_insert_iterator与back_inserter的介绍之后,我总算明白了:back_insert_iterator, ...