学习总结
1、首先简单理解什么是socket
socket(套接字)是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。
2、什么是多线程,有什么用?
首先我们要理解什么是线程与多线程。
线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
多线程是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。
简单来说:线程是程序中一个单一的顺序控制流程;而多线程就是在单个进程中同时运行多个线程来完成不同的工作。
多线程的优缺点
优点:
1)、多线程技术可以加快程序的运行速度,使程序的响应速度更快,因为用户界面可以在进行其它工作的同时一直处于活动状态
2)、可以把占据长时间的程序中的任务放到后台去处理,同时执行其他操作,提高效率
3)、当前没有进行处理的任务时可以将处理器时间让给其它任务
4)、可以让同一个程序的不同部分并发执行,释放一些珍贵的资源如内存占用等等
5)、可以随时停止任务
6)、可以分别设置各个任务的优先级以优化性能
缺点:
1)、因为多线程需要开辟内存,而且线程切换需要时间因此会很消耗系统内存。
2)、线程的终止会对程序产生影响
3)、由于多个线程之间存在共享数据,因此容易出现线程死锁的情况
4)、对线程进行管理要求额外的 CPU开销。线程的使用会给系统带来上下文切换的额外负担。
3、代码实现
首先来完成一个服务端的创建
第一步需要先定义俩个全局变量
#define BUF_SIZE 100
//能够连接的最大数量
#define MAX_CLNT 256
//客户端的连接数
int clnt_cnt = 0;
//客户端的连接sock的容器
int clnt_socks[MAX_CLNT];
//线程锁
pthread_mutex_t mutx;
这俩个全局变量的作用:
操作系统可以看作时一个工厂,进程是生产线,线程就是在这条生产线上的工人。
而这俩个变量就是用来记录工人数量和存储工人组的。
//第一个变量代表工人的数目
int clnt_cnt = 0; //客户端链接个数
//第二个变量数组代表工人组
int clnt_socks[MAX_CLNT];//socket分机
第二步就是创建socket服务端
想要完成通信最少需要一个服务端和一个或者多个客户端
而服务端与客户端可以看成一个电话机的主机与分机
int serv_sock, clnt_sock;
struct sockaddr_in serv_adr, clnt_adr;
int clnt_adr_sz;
pthread_t t_id;
if(argc!=2) {
printf("Usage : %s <port>\n", argv[0]);
exit(1);
}
pthread_mutex_init(&mutx, NULL);
//1 安装一步电话机
serv_sock=socket(PF_INET, SOCK_STREAM, 0);
memset(&serv_adr, 0, sizeof(serv_adr));
//传输地址的地址族
serv_adr.sin_family=AF_INET;
//设置指定IPv4传输地址
//htonl 地址转化 INADDR_ANY 任何地址
serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);
//传输协议端口号
//当服务端与客户段端口号不同是将无法连接成功
serv_adr.sin_port=htons(atoi(argv[1]));
//2、分配地址和端口
if(bind(serv_sock, (struct sockaddr*) &serv_adr, sizeof(serv_adr))==-1)//判断分配是否成功 失败返回错误号
error_handling("bind() error");
//3、监听
if(listen(serv_sock, 5)==-1)
error_handling("listen() error"