Linux网络编程(四)
TCP虽然可以实现 IO非阻塞操作,但在实际应用时会对资源是否准备完毕进行循环测试,增加了不必要的CPU占用。
为了解决这种问题,应用多路复用的知识,select()监听信号。相关知识可以参考 linux文件读写 文件锁 select poll 。
服务端:
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/time.h>
- #include <sys/ioctl.h>
- #include <unistd.h>
- #include <netinet/in.h>
- #define PORT 4321
- #define MAX_QUE_CONN_NM 5
- #define MAX_SOCK_FD FD_SETSIZE
- #define BUFFER_SIZE 1024
- int main(){
- struct sockaddr_in server_sockaddr, client_sockaddr;
- int sin_size, count;
- fd_set inset, tmp_inset;
- int sockfd, client_fd, fd;
- char buf[BUFFER_SIZE];
- if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
- perror(”socket”);
- exit(1);
- }
- server_sockaddr.sin_family = AF_INET;
- server_sockaddr.sin_port = htons(PORT);
- server_sockaddr.sin_addr.s_addr = INADDR_ANY;
- bzero(&(server_sockaddr.sin_zero), 8);
- int i = 1;
- //设置socket的属性
- setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
- if (bind(sockfd, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr)) == -1){
- perror(”bind”);
- exit(1);
- }
- if(listen(sockfd, MAX_QUE_CONN_NM) == -1){
- perror(”listen”);
- exit(1);
- }
- printf(”listening….\n”);
- //清空select集合
- FD_ZERO(&inset);
- //将要检测的文件符加入
- FD_SET(sockfd, &inset);
- while(1){
- tmp_inset = inset;
- sin_size=sizeof(struct sockaddr_in);
- memset(buf, 0, sizeof(buf));
- printf(”run while…\n”);
- //程序在此阻塞,select返回一个文件符,并将其他文件符清空
- if (!(select(MAX_SOCK_FD, &tmp_inset, NULL, NULL, NULL) > 0)){
- perror(”select”);
- close(sockfd);
- exit(1);
- }
- printf(”run for…\n”);
- for (fd = 0; fd < MAX_SOCK_FD; fd++){
- if (FD_ISSET(fd, &tmp_inset) > 0) {
- printf(”fd is %d ,socket is %d\n”,fd,sockfd);
- if (fd == sockfd){
- if ((client_fd = accept(sockfd, (struct sockaddr *)&client_sockaddr, &sin_size))== -1){
- perror(”accept”);
- exit(1);
- }
- FD_SET(client_fd, &inset);
- printf(”New connection from %d(socket)\n”, client_fd);
- }else{
- if ((count = recv(fd, buf, BUFFER_SIZE, 0)) > 0){
- printf(”Received a message from %d: %s\n”, fd, buf);
- }else{
- close(fd);
- FD_CLR(fd, &inset);
- printf(”Client %d(socket) has left\n”, fd);
- }
- }
- } /* end of if FD_ISSET*/
- } /* end of for fd*/
- } /* end if while while*/
- close(sockfd);
- exit(0);
- }
#include <sys/types.h>
include <sys/socket.h>
include <stdio.h>
include <stdlib.h>
include <string.h>
include <sys/time.h>
include <sys/ioctl.h>
include <unistd.h>
include <netinet/in.h>
define PORT 4321
define MAX_QUE_CONN_NM 5
define MAX_SOCK_FD FD_SETSIZE
define BUFFER_SIZE 1024
int main(){
struct sockaddr_in server_sockaddr, client_sockaddr;
int sin_size, count;
fd_set inset, tmp_inset;
int sockfd, client_fd, fd;
char buf[BUFFER_SIZE];
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){perror("socket");exit(1);
}server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(PORT);
server_sockaddr.sin_addr.s_addr = INADDR_ANY;
bzero(&(server_sockaddr.sin_zero), 8);int i = 1;
//设置socket的属性
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
if (bind(sockfd, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr)) == -1){perror("bind");exit(1);
}if(listen(sockfd, MAX_QUE_CONN_NM) == -1){perror("listen");exit(1);
}
printf("listening....\n");
//清空select集合
FD_ZERO(&inset);
//将要检测的文件符加入 FD_SET(sockfd, &inset);
while(1){tmp_inset = inset; sin_size=sizeof(struct sockaddr_in);memset(buf, 0, sizeof(buf));printf("run while...\n");//程序在此阻塞,select返回一个文件符,并将其他文件符清空if (!(select(MAX_SOCK_FD, &tmp_inset, NULL, NULL, NULL) > 0)){ perror("select");close(sockfd);exit(1);}printf("run for...\n");for (fd = 0; fd < MAX_SOCK_FD; fd++){if (FD_ISSET(fd, &tmp_inset) > 0) {printf("fd is %d ,socket is %d\n",fd,sockfd);if (fd == sockfd){ if ((client_fd = accept(sockfd, (struct sockaddr *)&client_sockaddr, &sin_size))== -1){perror("accept");exit(1);}FD_SET(client_fd, &inset);printf("New connection from %d(socket)\n", client_fd);}else{if ((count = recv(fd, buf, BUFFER_SIZE, 0)) > 0){printf("Received a message from %d: %s\n", fd, buf);}else{close(fd);FD_CLR(fd, &inset);printf("Client %d(socket) has left\n", fd);}}} /* end of if FD_ISSET*/} /* end of for fd*/
} /* end if while while*/close(sockfd);
exit(0);
}
客户端:
- <span style=“font-size:18px;”>#include <sys/types.h>
- #include <sys/socket.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/ioctl.h>
- #include <unistd.h>
- #include <netdb.h>
- #include <netinet/in.h>
- #define PORT 4321
- #define BUFFER_SIZE 1024
- int main(int argc, char *argv[]){
- int sockfd, sendbytes;
- char buf[BUFFER_SIZE];
- struct hostent *host;
- struct sockaddr_in serv_addr;
- if(argc < 3){
- fprintf(stderr,”USAGE: ./client Hostname(or ip address) Text\n”);
- exit(1);
- }
- if ((host = gethostbyname(argv[1])) == NULL){
- perror(”gethostbyname”);
- exit(1);
- }
- memset(buf, 0, sizeof(buf));
- sprintf(buf, ”%s”, argv[2]);
- if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1){
- perror(”socket”);
- exit(1);
- }
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_port = htons(PORT);
- serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
- bzero(&(serv_addr.sin_zero), 8);
- if(connect(sockfd,(struct sockaddr *)&serv_addr, sizeof(struct sockaddr))== -1){
- perror(”connect”);
- exit(1);
- }
- if ((sendbytes = send(sockfd, buf, strlen(buf), 0)) == -1){
- perror(”send”);
- exit(1);
- }
- sleep(30);
- close(sockfd);
- exit(0);
- }
- </span>
#include <sys/types.h>
include <sys/socket.h>
include <stdio.h>
include <stdlib.h>
include <string.h>
include <sys/ioctl.h>
include <unistd.h>
include <netdb.h>
include <netinet/in.h>
define PORT 4321
define BUFFER_SIZE 1024
int main(int argc, char *argv[]){
int sockfd, sendbytes;
char buf[BUFFER_SIZE];
struct hostent *host;
struct sockaddr_in serv_addr;
if(argc < 3){fprintf(stderr,"USAGE: ./client Hostname(or ip address) Text\n");exit(1);
}if ((host = gethostbyname(argv[1])) == NULL){perror("gethostbyname");exit(1);
}memset(buf, 0, sizeof(buf));
sprintf(buf, "%s", argv[2]);if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1){perror("socket");exit(1);
}serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(serv_addr.sin_zero), 8);if(connect(sockfd,(struct sockaddr *)&serv_addr, sizeof(struct sockaddr))== -1){perror("connect");exit(1);
}if ((sendbytes = send(sockfd, buf, strlen(buf), 0)) == -1){perror("send");exit(1);
}
sleep(30);
close(sockfd);
exit(0);
}
本篇博客出自 阿修罗道,转载出处:http://blog.csdn.net/fansongy/article/details/6901322
Linux网络编程(四)相关推荐
- Linux 网络编程四(socket多线程升级版)
//网络编程--客户端 #include <stdio.h> #include <stdlib.h> #include <string.h> #include &l ...
- 【Linux网络编程】TCP三次握手和四次挥手
00. 目录 文章目录 00. 目录 01. 三次握手 02. 四次挥手 03. 三次握手和四次挥手原因 04. 2MSL 05. 附录 01. 三次握手 在 TCP/IP 协议中,TCP 协议提供可 ...
- linux网络编程(四)线程池
linux网络编程(四)线程池 为什么会有线程池? 实现简单的线程池 为什么会有线程池? 大多数的服务器可能都有这样一种情况,就是会在单位时间内接收到大量客户端请求,我们可以采取接受到客户端请求创建一 ...
- 详情讲述Linux网络编程关注的问题丨epoll原理丨reactor模型丨三次挥手丨四次握手丨多线程丨单线程丨C/C++Linux丨C++后端开发
90分钟搞懂linux网络编程关注的问题 1. 三次挥手,四次握手 2. epoll实现原理剖析 3. reactor模型封装 单线程.多线程以及多进程 视频讲解如下,点击观看: 详情讲述Linux网 ...
- 【Linux】一步一步学Linux网络编程教程汇总(更新中......)
00. 目录 文章目录 00. 目录 01. 基础理论知识 02. 初级编程 03. 高级编程 04. LibEvent库 05. 06. 07. 01. 基础理论知识 [Linux网络编程]网络协议 ...
- Linux网络编程---详解TCP
Linux网络编程---详解TCP的三次握手和四次挥手_shanghx_123的博客-CSDN博客_tcp的协议数据单元被称为 TCP协议详解(TCP报文.三次握手.四次挥手.TIME_WAIT状态. ...
- Linux网络编程——黑马程序员笔记
01P-复习-Linux网络编程 02P-信号量生产者复习 03P-协议 协议: 一组规则. 04P-7层模型和4层模型及代表协议 分层模型结构: OSI七层模型: 物.数.网.传.会.表.应TCP/ ...
- Linux网络编程---I/O复用模型之select
https://blog.csdn.net/men_wen/article/details/53456435 Linux网络编程-I/O复用模型之select 1. IO复用模型 IO复用能够预先告知 ...
- linux网络编程(二)TCP通讯状态
linux网络编程(二)TCP通讯状态 TCP状态转换 为什么需要等待2MSL? 端口复用 TCP状态转换 tcp协议连接开始会经过三次握手,客户端和服务器开始都会处于CLOSED状态 第一次握手:客 ...
- linux网络编程(一)网络基础传输知识
linux网络编程(一)网络传输基础知识 一.什么是协议? 二.使用步骤 典型协议 2.网络应用程序设计模式 C/S模式 B/S模式 优缺点 3.分层模型 4.TCP/IP四层模型 通信过程 5.协议 ...
最新文章
- Android 屏幕适配从未如斯简单(8月10日最终更新版)
- exception in initAndListen: 12596 old lock file, terminating
- unbuntu18 netplan 配置固定IP
- 流式计算新贵Kafka Stream设计详解--转
- Python的IDE之PyCharm:PyCharm的使用技巧图文教程(修改Pycharm默认风格颜色、编辑器内代码注释区域的颜色、编辑器内的Python Interpreter等)之详细攻略
- 解决mysql 1032 主从错误
- [导入]c#中的关于string的转换的问题
- 将txt文件转换成xlsx文件及用matlab读取xlsx
- recv函数返回0_函数VLOOKUP与LOOKUP的PK,大战一触即发 Excel神技能!
- Excel导入-----导出(包含所选和全部)操作
- 用姿态补偿雷达数据畸变的文字想法
- 计算机控制系统中采样速率的选择
- php不包含_php 正则 不包含某字符串的正则表达式
- IM在线聊天-微聊即时通讯完整源码
- 勒索病毒代码python_一份勒索病毒解密工具的整理汇总
- ❤️对比PyWinAuto和uiautomation实现微信联系人自动采集❤️
- 汽车c语言标准 misra,MATLAB 和 Simulink 中的 MISRA C 支持
- 本地计算机的硬件基本配置信息,Windows7系统如何查看硬件的基本配置
- 计算机网络:四类数据编码技术
- v4l2框架—申请缓存(VIDIOC_REQBUFS)
热门文章
- 使用java抓取金山词霸的每日一句
- Java期末复习基础知识整理(有点长)
- Revit SDK 介绍:ModelessForm_ExternalEvent ModelessForm_IdlingEvent
- 遇见未来 | 对话朱贤文: PostgreSQL是一匹即将发力的黑马
- AtCoder Beginner Contest 190 D - Staircase Sequences
- 基于HL7的HIE平台
- Java基础 DAY05
- 苹果5完美越狱_checkra1n for Mac(越狱工具)
- 视频封面如何消重 修改视频md5 百度网盘
- SQL使用函数处理数据