日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux多进程网络实例,Linux下一个单进程并发服务器的实例 使用select

發(fā)布時間:2025/3/20 linux 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux多进程网络实例,Linux下一个单进程并发服务器的实例 使用select 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

/*單進(jìn)程并發(fā)服務(wù)器實例。該程序采用單進(jìn)程并發(fā)服務(wù)器算法實現(xiàn)的。*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define PORT 1234?????????? //服務(wù)器端口

#define BACKLOG 5?????????? //listen隊列中等待的連接數(shù)

#define MAXDATASIZE 1024 //緩沖區(qū)大小

typedef struct _CLIENT{??????? //客戶端結(jié)構(gòu)體

int?????? fd;??????? //客戶端socket描述符

char*? name;

struct sockaddr_in addr;???? //客戶端地址信息結(jié)構(gòu)體

char* data;

} CLIENT;

void process_cli(CLIENT *client, char* recvbuf, int len);? //客戶請求處理函數(shù)

void savedata(char* recvbuf, int len, char* data);

main()

{

int??? i, maxi, maxfd,sockfd;

int??? nready;

ssize_t????? n;

fd_set????? rset, allset;??? //select所需的文件描述符集合

int listenfd, connectfd;???? //socket文件描述符

struct sockaddr_in server;???? //服務(wù)器地址信息結(jié)構(gòu)體

CLIENT client[FD_SETSIZE];???? //FD_SETSIZE為select函數(shù)支持的最大描述符個數(shù)

char recvbuf[MAXDATASIZE];??? //緩沖區(qū)

int sin_size;??????????? //地址信息結(jié)構(gòu)體大小

if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {??? //調(diào)用socket創(chuàng)建用于監(jiān)聽客戶端的socket

perror("Creating socket failed.");

exit(1);

}

int opt = SO_REUSEADDR;

setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));??? //設(shè)置socket屬性

bzero(&server,sizeof(server));

server.sin_family=AF_INET;

server.sin_port=htons(PORT);

server.sin_addr.s_addr = htonl (INADDR_ANY);

if (bind(listenfd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1) {??? //調(diào)用bind綁定地址

perror("Bind error.");

exit(1);

}

if(listen(listenfd,BACKLOG) == -1){????? //調(diào)用listen開始監(jiān)聽

perror("listen() error\n");

exit(1);

}

sin_size=sizeof(struct sockaddr_in);

//初始化select

maxfd = listenfd;

maxi = -1;

for (i = 0; i < FD_SETSIZE; i++) {

client[i].fd = -1;

}

FD_ZERO(&allset);??????? //清空

FD_SET(listenfd, &allset);??? //將監(jiān)聽socket加入select檢測的描述符集合

while(1)

{

struct sockaddr_in addr;

rset = allset;

nready = select(maxfd+1, &rset, NULL, NULL, NULL);??? //調(diào)用select

printf("select saw rset actions and the readfset num is %d. \n",nready );

if (FD_ISSET(listenfd, &rset)) {????? //檢測是否有新客戶端請求

printf("accept a connection.\n");

//調(diào)用accept,返回服務(wù)器與客戶端連接的socket描述符

if ((connectfd = accept(listenfd,(struct sockaddr *)&addr,(socklen_t *)&sin_size))==-1) {

perror("accept() error\n");

continue;

}

//將新客戶端的加入數(shù)組

for (i = 0; i < FD_SETSIZE; i++){

if (client[i].fd < 0) {

client[i].fd = connectfd;??? //保存客戶端描述符

client[i].name = new char[MAXDATASIZE];

client[i].addr = addr;

client[i].data = new char[MAXDATASIZE];

client[i].name[0] = '\0';

client[i].data[0] = '\0';

printf("You got a connection from %s.? ",inet_ntoa(client[i].addr.sin_addr) );

break;

}

}

printf("add new connect fd.\n");

if (i == FD_SETSIZE)

printf("too many clients\n");

FD_SET(connectfd, &allset);?? //將新socket連接放入select監(jiān)聽集合

if (connectfd > maxfd)

maxfd = connectfd;?? //確認(rèn)maxfd是最大描述符

if (i > maxi)????????? //數(shù)組最大元素值

maxi = i;

if (--nready <= 0)

continue;????? //如果沒有新客戶端連接,繼續(xù)循環(huán)

}

for (i = 0; i <= maxi; i++) {

if ( (sockfd = client[i].fd) < 0)?????? //如果客戶端描述符小于0,則沒有客戶端連接,檢測下一個

continue;

if (FD_ISSET(sockfd, &rset)) {??????? //檢測此客戶端socket是否有數(shù)據(jù)

printf("recv occured for connect fd[%d].\n",i);

if ( (n = recv(sockfd, recvbuf, MAXDATASIZE,0)) == 0) { //從客戶端socket讀數(shù)據(jù),等于0表示網(wǎng)絡(luò)中斷

close(sockfd);??????? //關(guān)閉socket連接

printf("Client( %s ) closed connection. User's data: %s\n",client[i].name,client[i].data);

FD_CLR(sockfd, &allset);??? //從監(jiān)聽集合中刪除此socket連接

client[i].fd = -1;??????? //數(shù)組元素設(shè)初始值,表示沒客戶端連接

delete client[i].name;

delete client[i].data;

} else

process_cli(&client[i], recvbuf, n);??? //接收到客戶數(shù)據(jù),開始處理

if (--nready <= 0)

break;?????? //如果沒有新客戶端有數(shù)據(jù),跳出for循環(huán)回到while循環(huán)

}

}

}

close(listenfd);? //關(guān)閉服務(wù)器監(jiān)聽socket

}

void process_cli(CLIENT *client, char* recvbuf, int len)

{

char sendbuf[MAXDATASIZE];

recvbuf[len-1] = '\0';

if (strlen(client->name) == 0) {

memcpy(client->name,recvbuf, len);

printf("Client's name is %s.\n",client->name);

return;

}

printf("Received client( %s ) message: %s\n",client->name, recvbuf);

savedata(recvbuf,len, client->data);

for (int i1 = 0; i1 < len - 1; i1++) {

sendbuf[i1] = recvbuf[len - i1 -2];

}

sendbuf[len - 1] = '\0';

send(client->fd,sendbuf,strlen(sendbuf),0);

}

void savedata(char* recvbuf, int len, char* data)

{

int start = strlen(data);

for (int i = 0; i < len; i++) {

data[start + i] = recvbuf[i];

}

}

總結(jié)

以上是生活随笔為你收集整理的linux多进程网络实例,Linux下一个单进程并发服务器的实例 使用select的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。