为什么80%的码农都做不了架构师?>>>
上一篇中说到了第一种方法,Fork,
这里在使用另一种方法:thread (线程)。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <pthread.h>
#define PORT_NUM (2227) //定义端口号。
#define BUFFSIZE (1024)
#define CMD_ONE ("1")
#define CMD_TWO ("2")
#define CMD_THREE ("3")
#define CMD_CODE_ERR (0)
#define CMD_CODE_ONE (1)
#define CMD_CODE_TWO (2)
#define CMD_CODE_THREE (3)
#define LISTEN_QUE (10)
#define LOG_MSG(format, ...) do{fprintf(stderr, "[MessageInfo]: "format" \n", ##__VA_ARGS__);}while(0)
typedef struct socklnk_st{
int32_t sd;
struct socklnk_st *next;
}socklnk_t;
socklnk_t*
create_soclnk(int32_t data)
{
socklnk_t *soclnk = NULL;
soclnk = (socklnk_t *)malloc(sizeof(socklnk_t));
if(soclnk != NULL){
soclnk->next = NULL;
soclnk->sd = data;
}
return soclnk;
}
void
free_soclnk(socklnk_t *dst)
{
socklnk_t *tmp = dst;
socklnk_t *next;
while(tmp != NULL){
next = tmp->next;
close(tmp->sd);
free(tmp);
tmp = next;
}
}
//定义每个Code返回值。
static int8_t *server_msg[] = {
[CMD_CODE_ONE] = "Hello",
[CMD_CODE_TWO] = "Good",
[CMD_CODE_THREE] = "Bye",
[CMD_CODE_ERR] = "Error Command",
};
socklnk_t *
start_serice(uint16_t port)
{
int8_t serv[NI_MAXSERV];
int32_t sd;
int32_t opt = 1;
struct addrinfo *ai, *res = NULL;
struct addrinfo hints;
socklnk_t *head = NULL;
socklnk_t *cur = NULL;
if(snprintf(serv, NI_MAXSERV, "%u", port) < 0){
goto func_end;
}
(void)memset(&hints, 0x00, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if(getaddrinfo(NULL, serv, &hints, &res) != 0){
goto func_end;
}
for(ai = res; ai != NULL; ai = ai->ai_next){
sd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if(sd < 0){
continue;
}
if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof opt) < 0){
close(sd);
free_soclnk(head);
goto func_end;
}
if(bind(sd, ai->ai_addr, ai->ai_addrlen) < 0){
close(sd);
continue;
}
if(listen(sd, LISTEN_QUE) < 0){
close(sd);
continue;
}
if(head == NULL){
head = create_soclnk(sd);
if(head == NULL){
close(sd);
free_soclnk(head);
goto func_end;
}
cur = head;
}else{
cur->next = create_soclnk(sd);
if(cur->next == NULL){
close(sd);
free_soclnk(head);
goto func_end;
}
cur = cur->next;
}
}
func_end:
if(res != NULL){
freeaddrinfo(res);
}
return head;
}
void *
func_proc(void *arg)
{
int8_t *buf;
int32_t ret = -1;
int32_t *sd;
int32_t cmd;
int32_t sendlen;
int32_t connfd;
buf = (int8_t*)malloc(BUFFSIZE);
if(buf == NULL){
LOG_MSG("Service Process Failed");
goto func_end;
}
if(arg == NULL){
LOG_MSG("Service Process Failed");
goto func_end;
}
sd = (int32_t *)arg;
connfd = *sd;
for(;;){
(void)memset(buf, 0x00, BUFFSIZE);
if(read(connfd, buf, BUFFSIZE) > 0){
if(strncmp(buf, CMD_ONE, strlen(CMD_ONE)) == 0){
cmd = CMD_CODE_ONE;
}else if(strncmp(buf, CMD_TWO, strlen(CMD_TWO)) == 0){
cmd = CMD_CODE_TWO;
}else if(strncmp(buf, CMD_THREE, strlen(CMD_THREE)) == 0){
cmd = CMD_CODE_THREE;
}else{
cmd = CMD_CODE_ERR;
}
sendlen = strlen(server_msg[cmd]);
if(write(connfd, server_msg[cmd], sendlen) != sendlen){
close(connfd);
goto func_end;
}
if(cmd == CMD_CODE_THREE){
break;
}
}else{
break;
}
}
func_end:
if(buf != NULL){
free(buf);
}
close(connfd);
pthread_exit(NULL);
}
int
main(int ac, char **av)
{
int32_t connfd;
int32_t maxfd = -1;
fd_set fds;
pthread_t tid[10];
socklnk_t *sdlnk = NULL;
socklnk_t *this;
sdlnk = start_serice(PORT_NUM);
if(sdlnk == NULL){
LOG_MSG("Service Start Failed");
goto func_end;
}
//main Loops
for(;;){
FD_ZERO(&fds);
for(this = sdlnk; this != NULL; this = this->next){
FD_SET(this->sd, &fds);
if(this->sd > maxfd){
maxfd = this->sd;
}
}
if(select(maxfd + 1, &fds, NULL, NULL, NULL) > 0){
for(this = sdlnk; this != NULL; this = this->next){
if(FD_ISSET(this->sd, &fds) != 0){
if((connfd = accept(this->sd, NULL, NULL)) < 0){
continue;
}
break;
}
}
}else{
goto func_end;
}
if(this == NULL){
goto func_end;
}
if(pthread_create(&tid, NULL, func_proc, &connfd) != 0){
LOG_MSG("Service Process Failed");
close(connfd);
goto func_end;
}
}
func_end:
if(sdlnk != NULL){
free_soclnk(sdlnk);
}
return 0;
}