服务器

/* 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下使用多线程模拟异步网络通信的更多相关文章

  1. 【转】 Linux下的多线程编程

    作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/原文链接:http://www.cnblogs.com/gnuhpc/archive/2012/12/07/280 ...

  2. Linux下的多线程编程

    1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的 Unix也支持线程的概念,但是在一个进程(proces ...

  3. 【转】Linux下的多线程编程

    1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的 Unix也支持线程的概念,但是在一个进程(proces ...

  4. 《转》Linux下的多线程编程

    原地址:http://linux.chinaunix.net/doc/program/2001-08-11/642.shtml 1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程 ...

  5. linux下php pcntl_fork模拟多线程

    开始用php写后台服务一段时间了.也是在这样的驱动下,不断的学习php语法,体验这一原来一直以为神秘且敬而远之的神奇语言的魅力.最初看php多线程的资料是为了提高程序的处理能力,充分发挥linux多任 ...

  6. Linux下基于多线程的echo

    准备开始写一些Linux 下网络编程以及多线程的blog,就从这个简单的echo程序开始吧. 在echo的服务端使用多线程与客户进行通信,可以实现一个服务端程序同时连接多个客户的功能.那么,到底在服务 ...

  7. linux下的多线程,pthread_create函数

    pthread_create是UNIX环境创建线程函数 头文件 #include<pthread.h> 函数声明 int pthread_create(pthread_t*restrict ...

  8. 【转】Linux下的多线程编程背景知识

    1. 进程和线程 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的 Unix也支持线程的概念,但是在一个进程(pr ...

  9. linux下使用多线程编写的聊天室

    自从开始学linux网络编程后就想写个聊天室,一开始原本打算用多进程的方式来写,可是发觉进程间的通信有点麻烦,而且开销也大,后来想用多线程能不能实现呢,于是便去看了一下linux里线程的用法,实际上只 ...

随机推荐

  1. VC实用小知识总结 (一),转http://blog.csdn.net/myiszjf/article/details/10007431

    在上一篇中,我们以经介绍了程序的流程和框架,在本篇将详细讨论各个功能的实现主要包括 1.获取磁盘信息2.获取目录信息3.获取文件信息4.运行指定文件5.删除指定文件6.删除指定目录7.创建指定目录8. ...

  2. C++ Primer 5th 第6章 函数

    正如第一章所说:C++的函数是一个能够完成一个功能的模块或者说是一段命名了的代码块. 如下图所示,函数可以重载,是一段实现某些功能命名了的代码. 一个完整的函数的构成有四部分: 1.返回类型 2.函数 ...

  3. 前端技术-svg简介与snap.svg.js开源项目的使用

    前言-为什么学习snap.svg.js 前阵子webAPP的技术群里有人感觉到svg+animate的形式感觉很炫,矢量图任意放大且不需要下载图片,并且在手机端效果流畅. (矢量图与位图最大的区别是, ...

  4. [Mugeda HTML5技术教程之6]添加元素

    我们上节讲了怎么创建新作品.新作品创建好后,我们就可以在里面添加内容了.这一节,我们将要讲述如何在作品中添加元素.动画的中的内容都是以各种元素的形式组成的.对于添加到舞台上的元素,我们可以在时间线上添 ...

  5. jQuery Lazy Load 图片延迟加载

    基于 jQuery 的图片延迟加载插件,在用户滚动页面到图片之后才进行加载. 对于有较多的图片的网页,使用图片延迟加载,能有效的提高页面加载速度. 版本: jQuery v1.4.4+ jQuery ...

  6. PHP学习系列(1)——字符串处理函数(5)

    31.ord() 函数返回字符串第一个字符的 ASCII 值. 语法:ord(string) 例子 <?php echo ord("h"); echo ord("h ...

  7. Windows server 2012 各版本 激活方法

    Windows server 2012 激活教程 本文包括以下两种版本的激活过程:(注意RC版的是不能激活的!) 1.Windows server 2012 试用版本激活 2.Windows serv ...

  8. Qt也有垃圾回收(通过QScopedPointer实现),下决心在项目里使用QScopedPointer,省了太多事情了,而且更安全!!

    也谈Qt的垃圾回收 前几天在做代码审核的时候,Kai Uwe Broulik建议使用QScopedPointer来替代手工内存管理,使用后发觉确实节约了不少代码量,我的CHERRY可以延长寿命了!但是 ...

  9. QT下资源使用和资源占用…(可以动态加载资源文件,这样不占内存)

    原文地址:关于QT下资源使用和资源占用内存过多的问题作者:技术成就梦想     最近研究了一下如何从外部动态调用图片的问题,从而研究了图片资源的使用方法.网上最常见的帖子是这个,感觉总结的还不错. h ...

  10. linux下串口的阻塞和非阻塞操作

    有两个可以进行控制串口阻塞性(同时控制read和write):一个是在打开串口的时候,open函数是否带O_NDELAY:第二个是可以在打开串口之后通过fcntl()函数进行控制. 阻塞的定义: 对于 ...