socket编程之并发回射服务器3
在socket编程之并发回射服务器一文中,服务器采用多进程的方式实现并发,本文采用多线程的方式实现并发。
多线程相关API:
// Compile and link with -pthread
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
int pthread_join(pthread_t thread, void **retval); int pthread_detach(pthread_t thread);
pthread_join类似waitpid,用于等待一个线程的结束。
pthread_detach将线程状态变成detachable。
一个detachable线程终止后,它的资源自动释放回系统,不需要其他线程join。
具体代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/errno.h>
#include <pthread.h> #define MAXLINE 4096
#define LISTENQ 10
#define PORT 8888 void doEcho(int sockfd) {
char buff[MAXLINE];
while (true) {
memset(buff, , sizeof(buff));
int n = read(sockfd, buff, MAXLINE);
if (n < ) {
perror("read error");
exit();
} else if (n == ) {
printf("client closed\n");
break;
}
fputs(buff, stdout);
write(sockfd, buff, n);
}
} static void* doit(void *arg) {
int sockfd = *(int*)arg;
free(arg); pthread_detach(pthread_self());
doEcho(sockfd);
close(sockfd);
return (NULL);
} int main(int argc, char **argv) { int listenfd, connfd;
pthread_t tid;
socklen_t clilen;
struct sockaddr_in servaddr, cliaddr; if ( (listenfd = socket(AF_INET, SOCK_STREAM, )) < ) {
perror("socket error");
exit();
} bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT); if ( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < ) {
perror("bind error");
exit();
} if ( listen(listenfd, LISTENQ) < ) {
perror("listen error");
exit();
} for ( ; ; ) {
clilen = sizeof(cliaddr);
if ( (connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &clilen)) < ) {
if (errno == EINTR) {
continue;
} else {
perror("accept error");
exit();
}
} int *pconnfd = (int*)malloc(sizeof(int));
*pconnfd = connfd;
pthread_create(&tid, NULL, &doit, pconnfd);
}
}
需要注意的是给新线程传递参数的方法,不能直接传递connfd。
socket编程之并发回射服务器3的更多相关文章
- socket编程之并发回射服务器2
承接上文:socket编程之并发回射服务器 为了让服务器进程的终止一经发生,客户端就能检测到,客户端需要能够同时处理两个描述符:套接字和用户输入. 可以使用select达到这一目的: void str ...
- socket编程之并发回射服务器
使用到的函数: // 子进程返回0,父进程返回子进程ID,出错返回-1 pid_t fork(void); pid_t wait(int *wstatus); // 最常用的option是WNOHAN ...
- socket编程之时间回射服务器
使用到的函数: // 返回值:读到的字节数,若已到文件尾,返回0:若出错,返回-1 ssize_t read(int fd, void *buf, size_t nbytes); // 返回值:若成功 ...
- 第二十篇:不为客户连接创建子进程的并发回射服务器(poll实现)
前言 在上文中,我使用select函数实现了不为客户连接创建子进程的并发回射服务器( 点此进入 ).但其中有个细节确实有点麻烦,那就是还得设置一个client数组用来标记select监听描述符集中被设 ...
- 不为客户连接创建子进程的并发回射服务器( poll实现 )
前言 在上文中,我使用select函数实现了不为客户连接创建子进程的并发回射服务器( 点此进入 ).但其中有个细节确实有点麻烦,那就是还得设置一个client数组用来标记select监听描述符集中被设 ...
- 第十九篇:不为客户连接创建子进程的并发回射服务器(select实现)
前言 在此前,我已经介绍了一种并发回射服务器实现.它通过调用fork函数为每个客户请求创建一个子进程.同时,我还为此服务器添加了自动消除僵尸子进程的机制.现在请想想,在客户量非常大的情况下,这种为每个 ...
- 不为客户连接创建子进程的并发回射服务器( select实现 )
前言 在此前,我已经介绍了一种并发回射服务器实现( 点此进入 ).它通过调用fork函数为每个客户请求创建一个子进程.同时,我还为此服务器添加了自动消除僵尸子进程的机制.现在请想想,在客户量非常大的情 ...
- 【Unix网络编程】chapter5TCP回射服务器程序
chapter5 5.1 概述 5.2 TCP回射服务器程序:main函数 int main(int argc, char **argv) { int listenfd,connfd; pid_t ...
- 服务器编程入门(11)TCP并发回射服务器实现 - 单线程select实现
问题聚焦: 当客户端阻塞于从标准输入接收数据时,将读取不到别的途径发过来的必要信息,如TCP发过来的FIN标志. 因此,进程需要内核一旦发现进程指定的一个或多个IO条件就绪(即输入已准备好被读取,或者 ...
随机推荐
- Array(数组)对象-->unshift() 方法
1.定义和用法 unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度. 语法: array.unshift(item1,item2, ..., itemX) 参数:item1,it ...
- java解惑之常常忘记的事
java解惑之常常忘记的事 2012-10-17 18:38:57| 分类: JAVA | 标签:基础知识 软件开发 |举报|字号 订阅 针对刚接触java的菜鸟来说,java基础知识 ...
- .NET中 kafka消息队列、环境搭建与使用
前面几篇文章中讲了一些关于消息队列的知识,就每中消息队列中间件,我们并没有做详细的讲解,那么,今天我们就来详细的讲解一下消息队列之一kafka的一些基本的使用与操作. 一.kafka介绍 kafka: ...
- cmd命令行中查看、修改、删除与添加环境变量
注意:只在当前窗口生效!! 1.查看当前所有可用的环境变量:输入 set 即可查看. set 2.查看某个环境变量:输入 “set 变量名”即可 set python 3.修改环境变量 :输入 “se ...
- linux CVE-2019-14287 Sudo提权漏洞
CVE-2019-14287 sudo介绍 sudo,也就是以超级管理员身份运行(superuser do)的意思.sudo 是 Linux 中最常使用的重要实用程序之一,它功能十分强大,几乎安装在每 ...
- python+selenium实现网页自动化与爬虫技术
举例某购物网站,通过selenium与python,实现主页上商品的搜索,并将信息爬虫保存至本地excel表内. 一.python环境与selenium环境安装 python在官网下载并安装并且设置环 ...
- 【FishFX】花式撩骚,打造TypeScript易用框架。
· 栗子入手 假设有以下foo数组,数组中每个对象都拥有id,name两个属性,现在需要查找id > 0的对象数量. const foo: Array<{ id: number, name ...
- php静态变量的销毁
什么都不说,先上代码: public function _childrenids($data,$cate_id,$clear=false) { static $arr = array(); if ($ ...
- python学习23之标准库
'''''''''标准库1.datetime 日期时间模块存在于Lib/datetime.py文件内'''from datetime import datetime,date,time #from d ...
- python学习20之面向对象编程高级
'''''''''1.动态绑定:对于一个类,我们可以对它的实例动态绑定新的属性或方法.为了使所有的实例均可以使用动态绑定的属性和方法,我们也可以采用对类直接动态绑定'''class Student() ...