欢迎光临
我们一直在努力

多线程服务器与客户端文件传输(多线程并发服务器服务器框架框架框架)

tcp 多线程并发服务器

多线程服务器是对多进程服务器的改进。由于多进程服务器在创建进程时会消耗大量的系统资源,因此使用线程来替换进程,这样可以更快地创建服务处理器。据统计,创建线程和创建进程要快10100倍,因此线程被称为“轻量级”进程。线程与进程的区别在于,一个进程中的所有线程共享相同的信息,例如全局内存、全局变量等。这种机制带来了同步问题。

tcp多线程并发服务器框架:

我们在使用多线程并发服务器的时候,直接使用上面的框架,我们只修改()里面的内容。

代码示例:

#

#

#

#

#

#

#

#

/************************************************* *** ************************

函数名:void *(void *arg)

函数函数:线程函数,处理客户信息

功能参数:连接的

函数返回:无

****************************************************** ** *********************/

无效*(无效*arg)

{

= 0;

[1024] = “”; // 接收缓冲区

= (int)arg; //传入连接的套接字

// 接收数据

而(( = recv(, ,(), 0)) > 0)

{

(“: %s\n”, ); // 打印数据

发送(,,,,0);// 将数据发送回客户端

}

(” !\n”);

关(); //关闭连接的

;

}

//================================================= ==== ================

// 语法:void main(void)

// 实现函数:main函数,建立TCP并发服务器

//入口参数:无

// 退出参数:无

//================================================= ==== ================

(,char*argv[])

{

= 0; // 插座

= 0;

= 0;

; // 服务器地址结构

= 8080; // 监听端口

;

(“TCP 在端口 %d!\n”, 端口);

= (, , 0); // 创建一个 TCP 套接字

如果(<0)

{

(“错误”);

退出(-1);

}

bzero(&,()); //初始化服务器地址

. = ;

. = htons(端口);

.. = htonl();

(” 到端口 %d\n”, 端口);

// 绑定

= 绑定(, (*)&,());

如果(!= 0)

{

(“绑定”);

关();

退出(-1);

}

// 听着, 变成被动的

= (, 10);

如果(!= 0)

{

(“”);

关();

退出(-1);

}

(“…\n”);

而(1)

{

[] = “”; // 用于保存客户端IP地址

; // 用于保存客户端地址

=(); // 必须初始化!!!

// 获取已建立的连接 = (, (*)&, &);

如果(<0)

{

(“这次”);

;

}

//打印客户端的ip和端口

(, &., , );

(“———————————————— ————\n”);

(“ip=%s,端口=%d\n”, ,ntohs(.));

如果(> 0)

{

//因为同一个进程中的所有线程共享内存和变量,所以在传递参数时需要特殊处理,传值。

(&, NULL, (void*), (void*)); //创建线程

(); // 线程分离,最后自动回收资源

}

}

关();

;

}

运行结果:

注意:

1、上面()函数的最后一个参数是void *类型,为什么可以传值?

而(1)

{

= (, (*)&, &);

(&, NULL, (void*), (void*));

();

}

因为 void * 是 4 个字节,而 int 类型也是 4 个字节,所以可以传值。如果是char,short,上面的值会出错

2.上述()函数的最后一个参数可以传地址吗?可以,但会导致服务器出现不可预知的问题

而(1)

{

= (, (*)&, &);

(&, NULL, (void*), (void*)&);

();

}

原因:如果有多个客户端连接到这台服务器,一般情况下,一个客户端连接对应一个,互不影响。但是,如果多个客户端同时连接到这台服务器,客户端A的连接集不会受到影响。连接是服务器正在使用这个来处理数据,它还没有被处理。突然来了一个B客户端,()之后又生成了一个。因为是地址传输,所以A客户端的连接也变成了B的。在这种情况下,服务器必须不再是 A 的客户端服务器

2.如果要给线程函数传多个参数,首先考虑结构体参数,此时传值是不行的,只能传地址。

这时候就需要考虑多任务的互斥或者同步的问题了。在这里,我们使用互斥锁来解决这个问题正在连接服务器,并确保这个结构的参数值在允许修改之前保存在一个临时变量中。

#

互斥体;// 定义互斥锁,全局变量

(&mutex, NULL); // 初始化互斥量,互斥量默认开启

// 锁定,() 将阻塞,直到它被解锁

(&mutex);

= (, (*)&, &);

//传递给回调函数的参数,&,传递地址

(&, NULL, (void*), (void*)&); //创建线程

// 线程回调函数

无效*(无效*arg)

{

= *(int*)arg; // 传入的连接套接字

// 解锁, () 唤醒, 不阻塞 (&mutex);

;

}

示例代码:

#

#

#

#

#

#

#

#

互斥体;// 定义互斥锁,全局变量

/************************************************* *** ************************

函数名:void *(void *arg)

函数函数:线程函数,处理客户信息

功能参数:连接的

函数返回:无

****************************************************** ** *********************/

无效*(无效*arg)

{

= 0;

[1024] = “”; // 接收缓冲区

= *(int*)arg; // 传入的连接套接字

//解锁,()唤醒,不阻塞

(&mutex);

// 接收数据

而(( = recv(, ,(), 0)) > 0)

{

(“: %s\n”, ); // 打印数据

发送(,,,,0);// 将数据发送回客户端

}

(” !\n”);

关(); //关闭连接的

;

}

//================================================= ==== ================

// 语法:void main(void)

// 实现函数:main函数,建立TCP并发服务器

//入口参数:无

// 退出参数:无

//================================================= ==== ================

(,char*argv[])

{

= 0; // 插座

= 0;

= 0;

; // 服务器地址结构

= 8080; // 监听端口

;

(&mutex, NULL); // 初始化互斥量,互斥量默认开启

(“TCP 在端口 %d!\n”, 端口);

= (, , 0); // 创建一个 TCP 套接字

如果(<0)

{

(“错误”);

退出(-1);

}

bzero(&,()); //初始化服务器地址

. = ;

. = htons(端口);

.. = htonl();

(” 到端口 %d\n”, 端口);

// 绑定

= 绑定(, (*)&,());

如果(!= 0)

{

(“绑定”);

关();

退出(-1);

}

// 听着, 变成被动的

= (, 10);

如果(!= 0)

{

(“”);

关();

退出(-1);

}

(“…\n”);

而(1)

{

[] = “”; // 用于保存客户端IP地址

; // 用于保存客户端地址

=(); // 必须初始化!!!

// 锁定,() 将阻塞,直到它被解锁

(&mutex);

// 获取已建立的连接

= (, (*)&, &);

如果(<0)

{

(“这次”);

;

}

//打印客户端的ip和端口

(, &., , );

(“———————————————— ————\n”);

(“ip=%s,端口=%d\n”, ,ntohs(.));

如果(> 0)

{

//传递给回调函数的参数,&,传递地址

(&, NULL, (void*), (void*)&); //创建线程

(); // 线程分离,最后自动回收资源

}

}

关();

;

}

运行结果:

注意:这种互斥锁的使用对服务器的运行效率有致命的影响

需要C/C++ Linux服务器开发学习资料加(资料包括C/C++、Linux、技术、Nginx、MySQL、Redis、ZK、流媒体、CDN、P2P、K8S、TCP/IP、协程、DPDK等)得到

赞(0) 打赏
未经允许不得转载:艾飞特资源网 » 多线程服务器与客户端文件传输(多线程并发服务器服务器框架框架框架)
分享到

登录

找回密码

注册