中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站建設(shè)三要素寧波seo教學(xué)

網(wǎng)站建設(shè)三要素,寧波seo教學(xué),小草青青免費(fèi)觀看高清,世界知名設(shè)計(jì)公司名稱端口號快速復(fù)用函數(shù) 通過getsockopt和setsockopt函數(shù),管理套接字的端口號復(fù)用設(shè)置。具體操作如下: getsockopt函數(shù) int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);功能:獲取套接字的某些選項(xiàng)的屬性?!?article class="baidu_pl">

端口號快速復(fù)用函數(shù)

通過getsockoptsetsockopt函數(shù),管理套接字的端口號復(fù)用設(shè)置。具體操作如下:

getsockopt函數(shù)

int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);

功能:獲取套接字的某些選項(xiàng)的屬性。

參數(shù)

  1. sockfd: 套接字描述符。
  2. level: 獲取的層級(例如SOL_SOCKET)。
  3. optname: 要獲取的操作名稱(如SO_REUSEADDR)。
  4. optval: 獲取的值(0表示禁用,非0表示啟用)。
  5. optlen: 參數(shù)4的大小。

返回值: 成功返回0,失敗返回-1。


setsockopt函數(shù)

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

功能:設(shè)置套接字的某些選項(xiàng)的屬性。

參數(shù)

  1. sockfd: 套接字描述符。
  2. level: 設(shè)置的層級(例如SOL_SOCKET)。
  3. optname: 要設(shè)置的操作名稱(如SO_REUSEADDR)。
  4. optval: 設(shè)置的值(0表示禁用,非0表示啟用)。
  5. optlen: 參數(shù)4的大小。

返回值: 成功返回0,失敗返回-1。


示例代碼:端口號快速復(fù)用

// 獲取當(dāng)前端口號是否能快速復(fù)用
int n;
int len = sizeof(n);
getsockopt(oldfd, SOL_SOCKET, SO_REUSEADDR, &n, &len);
if (n == 0) {printf("端口號快速復(fù)用未啟動\n");
} else {printf("端口號快速復(fù)用已經(jīng)啟動\n");
}// 設(shè)置當(dāng)前套接字端口號快速復(fù)用
n = 999;
setsockopt(oldfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));


1. 循環(huán)服務(wù)器模型

描述

循環(huán)服務(wù)器模型是一次只處理一個客戶端請求的傳統(tǒng)方式,處理完一個客戶端請求后,才會繼續(xù)處理下一個客戶端請求。由于其效率較低,每次只能執(zhí)行單個任務(wù),因此在高并發(fā)場景下表現(xiàn)不佳。

在循環(huán)服務(wù)器模型中,服務(wù)器端采用了一個循環(huán)來不斷接收客戶端請求。每當(dāng)一個客戶端連接成功后,服務(wù)器創(chuàng)建一個新的套接字用于通信,并處理客戶端的請求。每處理完一個客戶端請求后,服務(wù)器繼續(xù)等待下一個客戶端的連接。

主要步驟:

  1. 創(chuàng)建套接字:使用 socket() 函數(shù)創(chuàng)建套接字。
  2. 綁定:將套接字與服務(wù)器的 IP 地址和端口號綁定。
  3. 監(jiān)聽:開始監(jiān)聽客戶端連接請求。
  4. 循環(huán)接收客戶端請求
    • 每次 accept() 成功后,創(chuàng)建一個新的套接字用于通信。
    • 循環(huán)收發(fā)信息,直到客戶端斷開連接。
  5. 關(guān)閉連接:每次客戶端斷開連接后,關(guān)閉相應(yīng)的套接字。
  6. 關(guān)閉監(jiān)聽套接字

循環(huán)服務(wù)器代碼實(shí)現(xiàn)

代碼示例
#include <myhead.h>
#define IP "192.168.60.45"
#define PORT 6666
#define BACKLOG 20int main(int argc, const char *argv[]) {// 1. 創(chuàng)建套接字int oldfd = socket(AF_INET, SOCK_STREAM, 0);  // IPV4, TCP協(xié)議if (oldfd == -1) {perror("socket");return -1;}// 2. 獲取端口號屬性,查看是否啟用端口號快速復(fù)用int n;int len = sizeof(n);if (getsockopt(oldfd, SOL_SOCKET, SO_REUSEADDR, &n, &len) == -1) {perror("getsockopt");return -1;}if (n) {printf("端口號快速復(fù)用已經(jīng)啟動\n");} else {printf("端口號快速復(fù)用未啟動\n");}// 設(shè)置端口號快速復(fù)用n = 999;if (setsockopt(oldfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1) {perror("setsockopt");return -1;}printf("端口號快速復(fù)用成功\n");// 3. 綁定IP和端口號struct sockaddr_in server = {.sin_family = AF_INET,  // IPV4.sin_port = htons(PORT),  // 端口號轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)序.sin_addr.s_addr = inet_addr(IP),  // IP地址};if (bind(oldfd, (struct sockaddr *)&server, sizeof(server)) == -1) {perror("bind");return -1;}// 4. 監(jiān)聽if (listen(oldfd, BACKLOG) == -1) {perror("listen");return -1;}// 5. 接受客戶端連接請求并創(chuàng)建新的描述符用于通信struct sockaddr_in client;socklen_t client_len = sizeof(client);int newfd;while (1) {newfd = accept(oldfd, (struct sockaddr *)&client, &client_len);if (newfd == -1) {perror("accept");return -1;}printf("%s發(fā)來連接請求\n", inet_ntoa(client.sin_addr));// 6. 循環(huán)收發(fā)信息char buff[1024];while (1) {memset(buff, 0, sizeof(buff));int len = recv(newfd, buff, sizeof(buff), 0);  // 接收客戶端信息if (len == 0) {  // 客戶端斷開連接printf("客戶端下線\n");break;}printf("%s\n", buff);strcat(buff, "5201314");  // 添加回復(fù)信息send(newfd, buff, sizeof(buff), 0);  // 發(fā)送信息}}// 關(guān)閉套接字close(oldfd);close(newfd);return 0;
}
代碼流程:
  1. 創(chuàng)建套接字socket() 函數(shù)創(chuàng)建一個 TCP 套接字。
  2. 設(shè)置端口號復(fù)用:通過 setsockopt() 設(shè)置端口復(fù)用,允許在同一端口上建立多個連接。
  3. 綁定:使用 bind() 將套接字與 IP 地址和端口綁定。
  4. 監(jiān)聽:調(diào)用 listen() 使套接字進(jìn)入監(jiān)聽狀態(tài),準(zhǔn)備接受客戶端連接。
  5. 接受連接:通過 accept() 接受客戶端連接,返回一個新的套接字描述符用于與客戶端通信。
  6. 收發(fā)消息:在循環(huán)內(nèi)通過 recv() 接收客戶端消息,然后用 send() 發(fā)送回應(yīng)消息。直到客戶端斷開連接。
  7. 關(guān)閉套接字:處理完成后關(guān)閉套接字。
缺點(diǎn):
  • 同步阻塞:當(dāng)前的設(shè)計(jì)是同步阻塞的,服務(wù)器在處理一個客戶端請求時不能同時處理其他客戶端的請求。因此,如果有多個客戶端連接,必須等待前一個客戶端的請求處理完成后才能繼續(xù)。
  • 客戶端阻塞:新客戶端要通信時,必須等到舊客戶端退出。服務(wù)器只能在當(dāng)前連接斷開后接受新的客戶端請求。
  • 新客戶端要通信時,必須等待舊客戶端退出。
改進(jìn):

為了解決這個問題,可以采用 多線程多進(jìn)程 模型來并發(fā)處理客戶端請求,從而避免客戶端之間的阻塞。


2. 基于TCP的并發(fā)服務(wù)器

2.1 多進(jìn)程并發(fā)服務(wù)器

多進(jìn)程并發(fā)服務(wù)器的模型通常由一個父進(jìn)程負(fù)責(zé)監(jiān)聽客戶端的連接請求,每當(dāng)接收到一個連接請求時,父進(jìn)程創(chuàng)建一個新的子進(jìn)程來處理與客戶端的通信。父進(jìn)程和子進(jìn)程之間通過文件描述符傳遞數(shù)據(jù)。父進(jìn)程負(fù)責(zé)監(jiān)聽和接收客戶端連接,子進(jìn)程則處理數(shù)據(jù)收發(fā)。

多進(jìn)程服務(wù)器模型的關(guān)鍵問題:

1. 子進(jìn)程在哪創(chuàng)建: 父進(jìn)程在接收到客戶端的連接請求時會創(chuàng)建一個子進(jìn)程來處理該請求。

示例代碼:

pid_t pid = fork();
if (pid > 0) 
{// 父進(jìn)程:繼續(xù)監(jiān)聽新的連接請求,關(guān)閉新文件描述符close(newfd);
} 
else if (pid == 0) 
{// 子進(jìn)程:關(guān)閉舊的監(jiān)聽套接字,并處理客戶端通信close(server_fd);// 與客戶端通信...close(newfd); // 處理完成后關(guān)閉與客戶端的連接exit(0); // 子進(jìn)程處理完請求后退出
} 
else 
{perror("fork");return -1;
}

2. 子進(jìn)程怎么回收:子進(jìn)程處理完任務(wù)后會退出,因此需要確保父進(jìn)程能夠回收已經(jīng)退出的子進(jìn)程,防止僵尸進(jìn)程的產(chǎn)生。

常見的方式:

  • 阻塞回收:父進(jìn)程使用 wait()waitpid() 函數(shù)在子進(jìn)程退出時阻塞等待并回收它們。
  • 非阻塞回收:如果不想讓父進(jìn)程被 wait() 阻塞,可以使用信號處理機(jī)制,通過捕捉 SIGCHLD 信號并在信號處理函數(shù)中回收子進(jìn)程。

示例代碼(非阻塞回收):

// 信號處理函數(shù),用于回收僵尸進(jìn)程
void handle_sigchld(int sig) {while (waitpid(-1, NULL, WNOHANG) > 0);  // 回收已退出的子進(jìn)程
}// 在主程序中捕捉 SIGCHLD 信號
signal(SIGCHLD, handle_sigchld);

3. 文件描述符: 由于系統(tǒng)對打開的文件描述符有限制,因此需要確保在父子進(jìn)程中正確管理文件描述符。

在操作系統(tǒng)中,文件描述符是有限的,每個進(jìn)程可以打開的文件(包括套接字)的數(shù)量是有限的。如果服務(wù)器并發(fā)連接數(shù)較多,且每個連接都創(chuàng)建一個新的子進(jìn)程,就可能遇到文件描述符耗盡的問題??梢酝ㄟ^以下方式解決或避免這一問題:

解決方案:

  • 增加文件描述符限制:可以通過 ulimit -n 命令臨時增加系統(tǒng)的文件描述符限制,或者在 /etc/security/limits.conf 文件中永久增加限制。
  • 使用線程池或連接池:而不是為每個客戶端創(chuàng)建一個新的子進(jìn)程,可以通過線程池或連接池來管理客戶端連接。多線程或線程池模型可以減少系統(tǒng)開銷,因?yàn)榫€程的創(chuàng)建和銷毀比進(jìn)程更加輕量。
  • 復(fù)用文件描述符:通過一些技術(shù)手段(例如 select()、poll()epoll())來管理多個連接,不需要為每個客戶端創(chuàng)建一個獨(dú)立的進(jìn)程或線程,從而避免耗盡文件描述符。

示例:修改文件描述符限制

  1. 臨時修改文件描述符的限制:
ulimit -n 65535
  1. 永久修改文件描述符的限制: 在 /etc/security/limits.conf 文件中添加:?
* soft nofile 65535
* hard nofile 65535

總結(jié)

  1. 子進(jìn)程創(chuàng)建:父進(jìn)程在接收到客戶端連接請求后,使用 fork() 創(chuàng)建子進(jìn)程來處理該客戶端的通信。
  2. 子進(jìn)程回收:父進(jìn)程可以通過 wait()waitpid() 回收子進(jìn)程,也可以通過信號處理函數(shù)來非阻塞回收已退出的子進(jìn)程。
  3. 文件描述符限制:多進(jìn)程模型可能會受到系統(tǒng)文件描述符限制的影響,解決方法包括增加文件描述符限制、使用線程池或連接池等技術(shù)來減少文件描述符的占用。
多進(jìn)程并發(fā)服務(wù)器執(zhí)行模型:

定義信號處理函數(shù),非阻塞回收僵尸進(jìn)程。

綁定子進(jìn)程退出時的信號。

  1. 創(chuàng)建套接字
  2. 綁定
  3. 監(jiān)聽
  4. 循環(huán)接收客戶端連接
  5. 讓父進(jìn)程接收客戶端請求并關(guān)閉新文件描述符,子進(jìn)程關(guān)閉舊的描述符只負(fù)責(zé)數(shù)據(jù)收發(fā)。
多進(jìn)程服務(wù)器代碼:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <wait.h>#define IP "192.168.60.45"
#define PORT 6666
#define BACKLOG 100// 信號處理函數(shù),用于回收僵尸進(jìn)程
void fun(int sss)
{if (sss == SIGCHLD){while (waitpid(-1, NULL, 0) > 0); // 循環(huán)回收子進(jìn)程}
}int main(int argc, const char *argv[])
{// 1. 捕獲子進(jìn)程退出時的信號if (signal(SIGCHLD, fun) == SIG_ERR){perror("signal");return -1;}// 2. 創(chuàng)建TCP類型的套接字int oldfd = socket(AF_INET, SOCK_STREAM, 0);if (oldfd == -1){perror("socket");return -1;}// 3. 設(shè)置端口號快速復(fù)用int n = 1;if (setsockopt(oldfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1){perror("setsockopt");return -1;}printf("端口號快速復(fù)用成功\n");// 4. 綁定struct sockaddr_in server = {.sin_family = AF_INET,.sin_port = htons(PORT),.sin_addr.s_addr = inet_addr(IP),};if (bind(oldfd, (struct sockaddr *)&server, sizeof(server)) == -1){perror("bind");return -1;}// 5. 監(jiān)聽if (listen(oldfd, BACKLOG) == -1){perror("listen");return -1;}struct sockaddr_in client;socklen_t client_len = sizeof(client);char buff[1024];// 6. 主循環(huán)接收客戶端連接while (1){int newfd = accept(oldfd, (struct sockaddr *)&client, &client_len); // 接收客戶端連接printf("%s發(fā)來連接請求\n", inet_ntoa(client.sin_addr));pid_t pid = fork(); // 創(chuàng)建子進(jìn)程if (pid > 0) // 父進(jìn)程監(jiān)聽,并關(guān)閉新的描述符{close(newfd);}else if (pid == 0) // 子進(jìn)程處理數(shù)據(jù)收發(fā){close(oldfd); // 子進(jìn)程關(guān)閉舊的描述符while (1){int len = recv(newfd, buff, sizeof(buff), 0);if (len == 0){printf("客戶端退出\n");break;}printf("客戶端%s發(fā)來消息:%s\n", inet_ntoa(client.sin_addr), buff);strcat(buff, inet_ntoa(client.sin_addr)); // 回去時加上客戶端IPsend(newfd, buff, sizeof(buff), 0);}close(newfd);exit(0); // 子進(jìn)程退出}else{perror("fork");return -1;}}return 0;
}

客戶端代碼:

客戶端通過連接到服務(wù)器來發(fā)送數(shù)據(jù)并接收服務(wù)器的響應(yīng)。該程序創(chuàng)建一個TCP套接字,連接到指定的服務(wù)器IP和端口,并與服務(wù)器進(jìn)行數(shù)據(jù)交互。

#include <myhead.h>#define IP "192.168.60.45"
#define PORT 6666int main(int argc, const char *argv[])
{// 1. 創(chuàng)建套接字int oldfd = socket(AF_INET, SOCK_STREAM, 0);if (oldfd == -1){perror("socket");return -1;}// 2. 連接服務(wù)器struct sockaddr_in server = {.sin_family = AF_INET,.sin_port = htons(PORT),.sin_addr.s_addr = inet_addr(IP),};if (connect(oldfd, (struct sockaddr *)&server, sizeof(server)) == -1){perror("connect");return -1;}// 3. 數(shù)據(jù)收發(fā)char buff[1024];while (1){fgets(buff, sizeof(buff), stdin); // 鍵盤輸入字符串buff[strlen(buff) - 1] = '\0';   // 去除換行符// 發(fā)送數(shù)據(jù)到服務(wù)器send(oldfd, buff, sizeof(buff), 0);// 接收服務(wù)器數(shù)據(jù)int len = recv(oldfd, buff, sizeof(buff), 0);if (len == 0){printf("服務(wù)器意外退出\n");break;}printf("接收服務(wù)器消息:%s\n", buff);}// 關(guān)閉套接字close(oldfd);return 0;
}

?總結(jié)
  • 多進(jìn)程并發(fā)模型: 通過父進(jìn)程監(jiān)聽和創(chuàng)建子進(jìn)程來處理每個客戶端的請求,使用fork創(chuàng)建子進(jìn)程,在子進(jìn)程中負(fù)責(zé)數(shù)據(jù)收發(fā),父進(jìn)程關(guān)閉新文件描述符,子進(jìn)程關(guān)閉舊文件描述符。通過信號處理函數(shù)回收子進(jìn)程,避免僵尸進(jìn)程。
  • TCP客戶端: 連接到服務(wù)器后,通過套接字發(fā)送數(shù)據(jù)并接收響應(yīng),支持實(shí)時數(shù)據(jù)交互。

這種模型適用于客戶端和服務(wù)器之間的實(shí)時通信,特別是在需要處理多個客戶端請求的場景中。


2.2 多線程并發(fā)服務(wù)器

1. 多線程的優(yōu)勢
  • 資源開銷小:線程的資源開銷比進(jìn)程小,創(chuàng)建和銷毀線程的速度比進(jìn)程快。
  • 響應(yīng)速度快:如果客戶端連接較多,可以通過線程池提前創(chuàng)建線程來分配給客戶端,減少響應(yīng)延遲。
  • 線程銷毀開銷小:線程占用資源較少,銷毀線程的資源開銷也較小。
2. 服務(wù)器模型
  • 主線程:負(fù)責(zé)監(jiān)聽客戶端連接。
  • 子線程:負(fù)責(zé)接收和發(fā)送數(shù)據(jù),與客戶端通信。
3. 服務(wù)器的工作流程
  1. 創(chuàng)建原始套接字:使用 socket() 創(chuàng)建一個 TCP 類型的套接字。
  2. 綁定 IP 地址和端口號:使用 bind() 綁定服務(wù)器的 IP 地址和端口。
  3. 監(jiān)聽客戶端連接:使用 listen() 開始監(jiān)聽客戶端的連接請求。
  4. 接收客戶端連接:使用 accept() 接收客戶端的連接請求,并為每個客戶端創(chuàng)建一個新線程。
  5. 線程處理客戶端請求:每個線程接收到客戶端消息后進(jìn)行處理并發(fā)送響應(yīng)。線程執(zhí)行完后退出。
4. 線程池
  • 為了處理大量并發(fā)請求,線程池的機(jī)制可以預(yù)先創(chuàng)建一定數(shù)量的線程,接收到客戶端請求時,從線程池中取出一個線程來處理該請求。
5. 代碼實(shí)現(xiàn)
#include <myhead.h>// 定義服務(wù)器的 IP 地址、端口號和最大連接數(shù)
#define IP "192.168.60.45"
#define PORT 9999
#define BACKLOG 10// 定義結(jié)構(gòu)體,用于傳遞客戶端信息和新文件描述符
typedef struct {struct sockaddr_in client; // 客戶端信息int newfd;                 // 新的文件描述符
} ZYJ;// 線程體函數(shù),處理與客戶端的通信
void *fun(void *sss) {// 獲取新文件描述符和客戶端信息int newfd = ((ZYJ *)sss)->newfd;struct sockaddr_in client = ((ZYJ *)sss)->client;// 打印客戶端的 IP 地址printf("%s發(fā)來信息\n", inet_ntoa(client.sin_addr));char buff[1024];while (1) {// 接收客戶端發(fā)來的消息int len = recv(newfd, buff, sizeof(buff), 0);if (len == 0) { // 客戶端退出printf("客戶端退出\n");break;}// 打印收到的消息printf("收到消息:%s\n", buff);// 在消息末尾加上 "1973"strcat(buff, "1973");// 將處理后的消息發(fā)送回客戶端send(newfd, buff, sizeof(buff), 0);}// 線程結(jié)束時退出pthread_exit(NULL);
}int main(int argc, const char *argv[]) {// 1. 創(chuàng)建套接字int oldfd = socket(AF_INET, SOCK_STREAM, 0);if (oldfd == -1) {perror("socket");return -1;}// 2. 綁定 IP 地址和端口號struct sockaddr_in server = {.sin_family = AF_INET,.sin_port = htons(PORT),.sin_addr.s_addr = inet_addr(IP),};if (bind(oldfd, (struct sockaddr *)&server, sizeof(server)) == -1) {perror("bind");return -1;}// 3. 監(jiān)聽客戶端的連接請求if (listen(oldfd, BACKLOG) == -1) {perror("listen");return -1;}struct sockaddr_in client;socklen_t client_len = sizeof(client);// 4. 主線程循環(huán)接收客戶端連接while (1) {int newfd = accept(oldfd, (struct sockaddr *)&client, &client_len); // 接收客戶端連接請求ZYJ sb;sb.newfd = newfd;          // 保存新的文件描述符sb.client = client;        // 保存客戶端信息pthread_t tid;// 5. 創(chuàng)建子線程處理客戶端請求tid = pthread_create(&tid, NULL, fun, &sb);if (tid == -1) {perror("pthread_create");return -1;}// 6. 將線程設(shè)為分離狀態(tài),系統(tǒng)會自動回收線程資源pthread_detach(tid);}return 0;
}
代碼功能
  1. 創(chuàng)建套接字:通過 socket() 創(chuàng)建一個 TCP 套接字。
  2. 綁定 IP 地址和端口:通過 bind() 將套接字綁定到指定的 IP 地址和端口號。
  3. 監(jiān)聽連接:調(diào)用 listen() 開始監(jiān)聽來自客戶端的連接請求,最多允許 BACKLOG 個連接排隊(duì)。
  4. 接受連接:主線程通過 accept() 接收客戶端的連接請求,并返回一個新的文件描述符 newfd 用于與客戶端進(jìn)行通信。
  5. 創(chuàng)建子線程:每當(dāng)接受到新的連接,主線程會通過 pthread_create() 創(chuàng)建一個子線程處理客戶端的消息傳遞和接收。每個子線程的處理邏輯通過 fun() 函數(shù)完成。
  6. 線程回收:通過 pthread_detach() 將線程設(shè)置為分離狀態(tài),子線程在完成后會自動回收資源,避免主線程等待子線程退出。
關(guān)鍵函數(shù)
  • socket():創(chuàng)建一個套接字。
  • bind():將套接字與本地的 IP 地址和端口號綁定。
  • listen():讓套接字進(jìn)入監(jiān)聽狀態(tài),準(zhǔn)備接受客戶端連接。
  • accept():阻塞等待客戶端連接,并返回一個新的套接字用于與客戶端通信。
  • pthread_create():創(chuàng)建新的線程來處理客戶端請求。
  • pthread_detach():將線程設(shè)為分離狀態(tài),線程結(jié)束后自動回收資源。
  • recv():接收客戶端發(fā)送的消息。
  • send():向客戶端發(fā)送消息。
適用場景

這個多線程模型適用于客戶端連接量較大或較為頻繁的場景。每個客戶端連接都會分配一個線程進(jìn)行處理,因此可以在短時間內(nèi)處理多個客戶端的請求。

線程池優(yōu)化

雖然該程序?yàn)槊總€連接創(chuàng)建了一個獨(dú)立的線程,但在實(shí)際應(yīng)用中,為了提高資源利用率和性能,可以引入線程池。線程池事先創(chuàng)建好一組線程,客戶端請求到來時從線程池中取出一個線程來處理,而不是每次都創(chuàng)建一個新的線程。這樣可以減少線程的創(chuàng)建和銷毀開銷。

注意事項(xiàng)
  • 多線程同步問題:雖然本例中沒有涉及多線程之間的共享資源,但在復(fù)雜應(yīng)用中可能需要考慮線程同步機(jī)制(如互斥鎖、條件變量等)。
  • 線程回收:線程被設(shè)為分離狀態(tài)(pthread_detach()),這樣可以在線程結(jié)束后由系統(tǒng)自動回收資源,而不需要調(diào)用 pthread_join()

總結(jié)

該程序展示了一個典型的多線程并發(fā)服務(wù)器模型,使用線程處理每個客戶端請求,減少了主線程的負(fù)擔(dān),提高了處理效率。通過 pthread_detach() 來自動回收資源,避免了線程泄露問題。


6.? 客戶端代碼示例
#include <myhead.h>#define IP "192.168.60.45"
#define PORT 9999int main(int argc, const char *argv[])
{// 1、創(chuàng)建套接字int oldfd = socket(AF_INET, SOCK_STREAM, 0);if (oldfd == -1){perror("socket");return -1;}// 2、連接服務(wù)器struct sockaddr_in server = {.sin_family = AF_INET,.sin_port = htons(PORT),.sin_addr.s_addr = inet_addr(IP),};if (connect(oldfd, (struct sockaddr *)&server, sizeof(server)) == -1){perror("connect");return -1;}// 3、數(shù)據(jù)收發(fā)char buff[1024];while (1){fgets(buff, sizeof(buff), stdin); // 鍵盤輸入字符串buff[strlen(buff) - 1] = '\0';   // 去除換行符// 發(fā)送數(shù)據(jù)到服務(wù)器send(oldfd, buff, sizeof(buff), 0);// 接收服務(wù)器數(shù)據(jù)int len = recv(oldfd, buff, sizeof(buff), 0);if (len == 0){printf("服務(wù)器意外退出\n");break;}printf("接收服務(wù)器消息:%s\n", buff);}// 關(guān)閉套接字close(oldfd);return 0;
}

http://www.risenshineclean.com/news/56489.html

相關(guān)文章:

  • 中衛(wèi)網(wǎng)站建設(shè)報(bào)價(jià)網(wǎng)址收錄入口
  • 綏化網(wǎng)站建設(shè)站長工具關(guān)鍵詞挖掘
  • 深圳品牌設(shè)計(jì)公司的發(fā)展怎么制作seo搜索優(yōu)化
  • 南昌net網(wǎng)站開發(fā)深圳門戶網(wǎng)站
  • 百度關(guān)鍵詞seo推廣推廣關(guān)鍵詞如何優(yōu)化
  • 怎么做外匯返傭的網(wǎng)站推廣普通話活動方案
  • 網(wǎng)站后臺搜索nba最新排行
  • 網(wǎng)站自動答題腳本怎么做seo項(xiàng)目是什么
  • 網(wǎng)站備案信息變更百度指數(shù)在線查詢前100
  • 網(wǎng)站是怎么優(yōu)化的亞洲長尾關(guān)鍵詞挖掘
  • 白銀網(wǎng)站建設(shè)網(wǎng)絡(luò)營銷策劃書8000字
  • 網(wǎng)站制作長沙百度指數(shù)如何提升
  • 網(wǎng)站留言如何做的seo網(wǎng)站編輯優(yōu)化招聘
  • 南陽網(wǎng)站托管百度百度網(wǎng)址大全
  • 怎么給網(wǎng)站做鏈接屏蔽一個產(chǎn)品的宣傳和推廣方案
  • 全球最熱門網(wǎng)站關(guān)鍵對話
  • 貴陽網(wǎng)站建設(shè)-中國互聯(lián)百度400電話
  • 讓人家做網(wǎng)站需要問什么問題網(wǎng)站模板源碼
  • 青島做網(wǎng)站的公司哪個比較好百度外鏈查詢工具
  • 網(wǎng)站高端建設(shè)智慧軟文
  • 經(jīng)濟(jì)網(wǎng)站建設(shè)信息流優(yōu)化師沒經(jīng)驗(yàn)可以做嗎
  • 政府政務(wù)公開網(wǎng)站建設(shè)云南疫情最新情況
  • 請別人做網(wǎng)站新手怎么做電商運(yùn)營
  • 中國建設(shè)銀行社??ňW(wǎng)站吸引客流的25個技巧
  • 創(chuàng)意經(jīng)濟(jì)型網(wǎng)站建設(shè)優(yōu)化師培訓(xùn)機(jī)構(gòu)
  • 做網(wǎng)站哪個編輯器好用關(guān)鍵詞優(yōu)化一年的收費(fèi)標(biāo)準(zhǔn)
  • 暴雪娛樂aso優(yōu)化運(yùn)營
  • 支付寶免簽約wordpressseo網(wǎng)站推廣報(bào)價(jià)
  • c2g的代表性電商平臺怎樣淘寶seo排名優(yōu)化
  • 利用百度云做網(wǎng)站百度關(guān)鍵詞排名推廣工具