• httpserver 下载服务器demo 以及libevent版本的 httpserver


    实现效果如下:

    图片可以直接显示 

    cpp h 这些可以直接显示 其他的 则是提示是否要下载

    单线程 还有bug

    代码如下  先放上来 

    1. #include "httpserver.h"
    2. #include "stdio.h"
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #define BURSIZE 1024
    14. int hex2dec(char c)
    15. {
    16. if ('0' <= c && c <= '9') {
    17. return c - '0';
    18. } else if ('a' <= c && c <= 'f') {
    19. return c - 'a' + 10;
    20. } else if ('A' <= c && c <= 'F') {
    21. return c - 'A' + 10;
    22. } else {
    23. return -1;
    24. }
    25. }
    26. char dec2hex(short int c)
    27. {
    28. if (0 <= c && c <= 9) {
    29. return c + '0';
    30. } else if (10 <= c && c <= 15) {
    31. return c + 'A' - 10;
    32. } else {
    33. return -1;
    34. }
    35. }
    36. /*
    37. * 编码一个url
    38. */
    39. void urlencode(char url[])
    40. {
    41. int i = 0;
    42. int len = strlen(url);
    43. int res_len = 0;
    44. char res[BURSIZE];
    45. for (i = 0; i < len; ++i) {
    46. char c = url[i];
    47. if (('0' <= c && c <= '9') ||
    48. ('a' <= c && c <= 'z') ||
    49. ('A' <= c && c <= 'Z') || c == '/' || c == '.') {
    50. res[res_len++] = c;
    51. } else {
    52. int j = (short int)c;
    53. if (j < 0)
    54. j += 256;
    55. int i1, i0;
    56. i1 = j / 16;
    57. i0 = j - i1 * 16;
    58. res[res_len++] = '%';
    59. res[res_len++] = dec2hex(i1);
    60. res[res_len++] = dec2hex(i0);
    61. }
    62. }
    63. res[res_len] = '\0';
    64. strcpy(url, res);
    65. }
    66. /*
    67. * 解码url
    68. */
    69. void urldecode(char url[])
    70. {
    71. int i = 0;
    72. int len = strlen(url);
    73. int res_len = 0;
    74. char res[BURSIZE];
    75. for (i = 0; i < len; ++i) {
    76. char c = url[i];
    77. if (c != '%') {
    78. res[res_len++] = c;
    79. } else {
    80. char c1 = url[++i];
    81. char c0 = url[++i];
    82. int num = 0;
    83. num = hex2dec(c1) * 16 + hex2dec(c0);
    84. res[res_len++] = num;
    85. }
    86. }
    87. res[res_len] = '\0';
    88. strcpy(url, res);
    89. }
    90. int CreateSocketFD()
    91. {
    92. int fd = 0;
    93. fd = socket(AF_INET,SOCK_STREAM,0);
    94. if(fd == -1)
    95. {
    96. perror("Scoket fd = -1");
    97. return 0;
    98. }
    99. int reuseport = 1;
    100. int ret = setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&reuseport,sizeof(reuseport));
    101. if(ret == -1)
    102. {
    103. perror("setsocketopt failed");
    104. return -1;
    105. }
    106. struct sockaddr_in addr;
    107. addr.sin_family = AF_INET;
    108. addr.sin_port = htons(8888);
    109. addr.sin_addr.s_addr = INADDR_ANY;
    110. ret = bind(fd,(struct sockaddr*)&addr,sizeof(addr));
    111. if(ret == -1)
    112. {
    113. perror("bind error");
    114. return -1;
    115. }
    116. ret = listen(fd,10);
    117. if(ret == -1)
    118. {
    119. perror("listen error ");
    120. return -1;
    121. }
    122. return fd;
    123. }
    124. int AcceptClients(int epoll_fd,int fd)
    125. {
    126. struct sockaddr addr;
    127. int cfd = accept(fd,NULL,NULL);
    128. if(cfd == -1)
    129. {
    130. perror("accept failed");
    131. }
    132. int flag = fcntl(cfd,F_GETFL);
    133. flag |= O_NONBLOCK;
    134. fcntl(cfd,F_SETFL,flag);
    135. struct epoll_event ev;
    136. ev.data.fd = cfd;
    137. ev.events = EPOLLIN|EPOLLET;
    138. int ret = epoll_ctl(epoll_fd,EPOLL_CTL_ADD,cfd,&ev);
    139. if(ret == -1)
    140. {
    141. perror("epoll ctl failed");
    142. return 0;
    143. }
    144. return 0;
    145. }
    146. const char *GetFileType(const char *filename)
    147. {
    148. const char *dot = strrchr(filename,'.');
    149. if(dot == NULL)
    150. {
    151. return "text/plain; charset=utf-8";
    152. }
    153. if(strcmp(dot,".jpg") == 0 ||strcmp(dot,".jpeg") == 0)
    154. {
    155. return "image/jpg";
    156. }
    157. if(strcmp(dot,".html") == 0 ||strcmp(dot,".htm") == 0)
    158. {
    159. return "text/html; charset=utf-8";
    160. }
    161. if(strcmp(dot,".png") == 0)
    162. {
    163. return "image/png";
    164. }
    165. if(strcmp(dot,".bmp") == 0)
    166. {
    167. return "image/bmp";
    168. }
    169. if(strcmp(dot,".gif") == 0)
    170. {
    171. return "image/gif";
    172. }
    173. if(strcmp(dot,".css") == 0)
    174. {
    175. return "text/css";
    176. }
    177. if(strcmp(dot,".mp3") == 0)
    178. {
    179. return "audio/mpeg";
    180. }
    181. return "text/plain; charset=utf-8";
    182. }
    183. int SendHead(int cfd,int status ,const char *desc,const char *type,int size)
    184. {
    185. char buf[4096] = {0};
    186. sprintf(buf,"http/1.1 %d %s\r\n",status,desc);
    187. sprintf(buf+strlen(buf),"content-type: %s\r\n",type);
    188. sprintf(buf+strlen(buf),"content-length: %d\r\n\r\n",size);
    189. printf("SendHead buf[%s]\n",buf);
    190. send(cfd,buf,strlen(buf),0);
    191. return 0;
    192. }
    193. int SendDir(const char *dirname,int cfd)
    194. {
    195. char buf[4096] = {0};
    196. sprintf(buf,"%s",dirname);
    197. printf("SendDir dirname=[%s]\n",dirname);
    198. struct dirent **namelist;
    199. int count = scandir(dirname,&namelist,NULL,alphasort);
    200. printf("SendDir count=[%d]\n",count);
    201. for(int i = 0;i< count;i++)
    202. {
    203. char *name = namelist[i]->d_name;
    204. struct stat st;
    205. char sub_path[1024]={0};
    206. sprintf(sub_path,"%s/%s",dirname,name);
    207. stat(sub_path,&st);
    208. if(S_ISDIR(st.st_mode))
    209. {
    210. sprintf(buf+strlen(buf),
    211. "
    212. ",name,name,st.st_size);
    213. }
    214. else
    215. {
    216. sprintf(buf+strlen(buf),
    217. "
    218. ",name,name,st.st_size);
    219. }
    220. printf("cfd:%d Sendbuf[%s]\n",cfd,buf);
    221. send(cfd,buf,strlen(buf),0);
    222. memset(buf,0,sizeof(buf));
    223. free(namelist[i]);
    224. }
    225. sprintf(buf,"
    226. %s%ld
      %s%ld
      "
      );
    227. printf("cfd:%d Sendbuf[%s]\n",cfd,buf);
    228. send(cfd,buf,strlen(buf),0);
    229. free(namelist);
    230. return 0;
    231. }
    232. int SendFile(const char* filename,int cfd)
    233. {
    234. int fd = open(filename,O_RDONLY);
    235. if(fd >0)
    236. {
    237. #if 0
    238. while(1)
    239. {
    240. char buf[1024];
    241. int len = read(fd,buf,sizeof buf);
    242. if(len >0)
    243. {
    244. send(cfd,buf,len,0);
    245. usleep(10);
    246. }
    247. else if(len == 0)
    248. {
    249. printf("Read file end\n");
    250. break;
    251. }
    252. else
    253. {
    254. perror("read error");
    255. }
    256. }
    257. #else
    258. off_t offset = 0;
    259. int file_size = lseek(fd,0,SEEK_END);
    260. lseek(fd,0,SEEK_SET);
    261. while(offset
    262. {
    263. int send_len = sendfile(cfd,fd,&offset,file_size-offset);
    264. if(send_len == -1)
    265. {
    266. if(errno == EAGAIN)
    267. {
    268. //perror("sendfile no data send");
    269. }
    270. else
    271. {
    272. perror("sendfile ret -1");
    273. }
    274. }
    275. else
    276. {
    277. printf("Send len:%d\n",send_len);
    278. }
    279. }
    280. #endif
    281. }
    282. else
    283. {
    284. perror("open file failed");
    285. }
    286. close(fd);
    287. return 0;
    288. }
    289. int ParseReqLine(const char *line,int cfd)
    290. {
    291. char method[12];
    292. char path[1024];
    293. printf("ParseReqLine=[%s]\n",line);
    294. int ret = sscanf(line,"%[^ ] %[^ ]",method,path);
    295. printf("sscanf ret = %d\n",ret);
    296. printf("method=[%s],path=[%s]\n",method,path);
    297. urldecode(path);
    298. printf("afterdecode path=[%s]\n",path);
    299. if(ret ==2 )
    300. {
    301. }
    302. else
    303. {
    304. printf("Reqest line parse failed\n");
    305. return -1;
    306. }
    307. if(strcasecmp(method,"get") == 0)
    308. {
    309. }
    310. else if(strcasecmp(method,"post")==0)
    311. {
    312. }
    313. else
    314. {
    315. return -1;
    316. }
    317. char *file = NULL;
    318. if(strcmp(path,"/") == 0)
    319. {
    320. file = "./";
    321. }
    322. else
    323. {
    324. file = path+1;
    325. }
    326. struct stat st;
    327. ret = stat(file,&st);
    328. if(ret == -1)
    329. {
    330. printf("file doest not exist\n");
    331. SendHead(cfd,404,"Not found",GetFileType(".html"),-1);
    332. SendFile("404.html",cfd);
    333. return -1;
    334. }
    335. if(S_ISDIR(st.st_mode))
    336. {
    337. printf("Directory\n");
    338. SendHead(cfd,200,"OK",GetFileType(".html"),-1);
    339. SendDir(file,cfd);
    340. }
    341. else
    342. {
    343. printf("File\n");
    344. SendHead(cfd,200,"OK",GetFileType(file),st.st_size);
    345. SendFile(file,cfd);
    346. }
    347. return 0;
    348. }
    349. int Request(int epoll_fd,int cfd)
    350. {
    351. char buffer[4096] = {0};
    352. char temp_buf[1024] = {0};
    353. int read_len = 0;
    354. int total = 0;
    355. while((read_len = recv(cfd,temp_buf,sizeof(temp_buf),0))>0)
    356. {
    357. if(total+read_len <sizeof(buffer))
    358. {
    359. memcpy(buffer+total,temp_buf,read_len);
    360. total+=read_len;
    361. }
    362. }
    363. if(read_len == -1 && errno == EAGAIN)
    364. {
    365. //读取数据结束
    366. char *p = strstr(buffer,"\r\n");
    367. if(p)
    368. {
    369. int len = p - buffer;
    370. buffer[len] = 0;
    371. ParseReqLine(buffer,cfd);
    372. }
    373. }
    374. else if(read_len == 0)
    375. {
    376. //Client close socket
    377. epoll_ctl(epoll_fd,EPOLL_CTL_DEL,cfd,NULL);
    378. close(cfd);
    379. }
    380. else
    381. {
    382. perror("recv error");
    383. }
    384. return 0;
    385. }
    386. int EPOLL_Run(int server_fd)
    387. {
    388. int epoll_fd = epoll_create(10);
    389. if(epoll_fd == -1)
    390. {
    391. perror("epoll_create failed");
    392. return 0;
    393. }
    394. struct epoll_event ev;
    395. ev.data.fd = server_fd;
    396. ev.events = EPOLLIN;
    397. int ret = epoll_ctl(epoll_fd,EPOLL_CTL_ADD,server_fd,&ev);
    398. if(ret == -1)
    399. {
    400. perror("epoll_ctl failed");
    401. return 0;
    402. }
    403. struct epoll_event events[512];
    404. while(true)
    405. {
    406. int nReady = epoll_wait(epoll_fd,events,512,-1);
    407. for(int i = 0;i
    408. {
    409. int fd = events[i].data.fd;
    410. if(fd == server_fd)
    411. {
    412. AcceptClients(epoll_fd,fd);
    413. }
    414. else
    415. {
    416. if(events[i].events &EPOLLOUT)
    417. {
    418. //g_writeable = true;
    419. printf("客户端可以写数据了");
    420. }
    421. if(events[i].events &EPOLLIN)
    422. {
    423. Request(epoll_fd,fd);
    424. }
    425. }
    426. }
    427. }
    428. return epoll_fd;
    429. }
    430. int main()
    431. {
    432. printf("Hello world\n");
    433. char work_dir[] = "/home/develop/httpserver";
    434. //chdir(work_dir);
    435. int server_fd = CreateSocketFD();
    436. if(server_fd <=0)
    437. {
    438. return 0;
    439. }
    440. EPOLL_Run(server_fd);
    441. close(server_fd);
    442. return 0;
    443. }

    以上  如果遇到大文件 比如mp3 文件的话  就没办法 预览  试听 下载大文件也有问题  

    跟踪发现是SendFile 那里有问题   会返回-1

    根据网上的例子 改了一个 基于libevent版本的  不会存在这个问题 

    1. #include "sushi.h"
    2. #include "stdio.h"
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. #include
    15. #include
    16. #include
    17. #include
    18. #include
    19. #include
    20. #include
    21. #include
    22. #include
    23. #include
    24. #include
    25. #include
    26. #include
    27. #include
    28. #include
    29. #include "event2/http.h"
    30. #include "event2/event.h"
    31. #include "event2/buffer.h"
    32. #include "event2/bufferevent.h"
    33. #include "event2/bufferevent_compat.h"
    34. #include "event2/http_struct.h"
    35. #include "event2/http_compat.h"
    36. #include "event2/util.h"
    37. #include "event2/listener.h"
    38. #include "event2/thread.h"
    39. #define MAX_EVENTS 100
    40. #define RECVBUFSIZ 20
    41. bool g_run_flag = true;
    42. void sig_handler(int signo)
    43. {
    44. g_run_flag = false;
    45. printf("\033[0;31mprogram exit by user cmd !!!!\033[0;39m\n");
    46. }
    47. #define BURSIZE 1024
    48. int hex2dec(char c)
    49. {
    50. if ('0' <= c && c <= '9') {
    51. return c - '0';
    52. } else if ('a' <= c && c <= 'f') {
    53. return c - 'a' + 10;
    54. } else if ('A' <= c && c <= 'F') {
    55. return c - 'A' + 10;
    56. } else {
    57. return -1;
    58. }
    59. }
    60. char dec2hex(short int c)
    61. {
    62. if (0 <= c && c <= 9) {
    63. return c + '0';
    64. } else if (10 <= c && c <= 15) {
    65. return c + 'A' - 10;
    66. } else {
    67. return -1;
    68. }
    69. }
    70. /*
    71. * 编码一个url
    72. */
    73. void urlencode(char url[])
    74. {
    75. int i = 0;
    76. int len = strlen(url);
    77. int res_len = 0;
    78. char res[BURSIZE];
    79. for (i = 0; i < len; ++i) {
    80. char c = url[i];
    81. if (('0' <= c && c <= '9') ||
    82. ('a' <= c && c <= 'z') ||
    83. ('A' <= c && c <= 'Z') || c == '/' || c == '.') {
    84. res[res_len++] = c;
    85. } else {
    86. int j = (short int)c;
    87. if (j < 0)
    88. j += 256;
    89. int i1, i0;
    90. i1 = j / 16;
    91. i0 = j - i1 * 16;
    92. res[res_len++] = '%';
    93. res[res_len++] = dec2hex(i1);
    94. res[res_len++] = dec2hex(i0);
    95. }
    96. }
    97. res[res_len] = '\0';
    98. strcpy(url, res);
    99. }
    100. /*
    101. * 解码url
    102. */
    103. void urldecode(char url[])
    104. {
    105. int i = 0;
    106. int len = strlen(url);
    107. int res_len = 0;
    108. char res[BURSIZE];
    109. for (i = 0; i < len; ++i) {
    110. char c = url[i];
    111. if (c != '%') {
    112. res[res_len++] = c;
    113. } else {
    114. char c1 = url[++i];
    115. char c0 = url[++i];
    116. int num = 0;
    117. num = hex2dec(c1) * 16 + hex2dec(c0);
    118. res[res_len++] = num;
    119. }
    120. }
    121. res[res_len] = '\0';
    122. strcpy(url, res);
    123. }
    124. const char *GetFileType(const char *filename)
    125. {
    126. const char *dot = strrchr(filename,'.');
    127. if(dot == NULL)
    128. {
    129. return "text/plain; charset=utf-8";
    130. }
    131. if(strcmp(dot,".jpg") == 0 ||strcmp(dot,".jpeg") == 0)
    132. {
    133. return "image/jpg";
    134. }
    135. if(strcmp(dot,".html") == 0 ||strcmp(dot,".htm") == 0)
    136. {
    137. return "text/html; charset=utf-8";
    138. }
    139. if(strcmp(dot,".png") == 0)
    140. {
    141. return "image/png";
    142. }
    143. if(strcmp(dot,".bmp") == 0)
    144. {
    145. return "image/bmp";
    146. }
    147. if(strcmp(dot,".gif") == 0)
    148. {
    149. return "image/gif";
    150. }
    151. if(strcmp(dot,".css") == 0)
    152. {
    153. return "text/css";
    154. }
    155. if(strcmp(dot,".mp3") == 0)
    156. {
    157. return "audio/mpeg";
    158. }
    159. return "text/plain; charset=utf-8";
    160. }
    161. int SendHead(struct bufferevent *event,int status ,const char *desc,const char *type,int size)
    162. {
    163. char buf[4096] = {0};
    164. sprintf(buf,"http/1.1 %d %s\r\n",status,desc);
    165. sprintf(buf+strlen(buf),"content-type: %s\r\n",type);
    166. sprintf(buf+strlen(buf),"content-length: %d\r\n\r\n",size);
    167. printf("SendHead buf[%s]\n",buf);
    168. //send(cfd,buf,strlen(buf),0);
    169. bufferevent_write(event,buf,strlen(buf));
    170. return 0;
    171. }
    172. int SendDir(struct bufferevent *event,const char *dirname)
    173. {
    174. char buf[4096] = {0};
    175. sprintf(buf,"%s",dirname);
    176. printf("SendDir dirname=[%s]\n",dirname);
    177. struct dirent **namelist;
    178. int count = scandir(dirname,&namelist,NULL,alphasort);
    179. printf("SendDir count=[%d]\n",count);
    180. for(int i = 0;i< count;i++)
    181. {
    182. char *name = namelist[i]->d_name;
    183. struct stat st;
    184. char sub_path[1024]={0};
    185. sprintf(sub_path,"%s/%s",dirname,name);
    186. stat(sub_path,&st);
    187. if(S_ISDIR(st.st_mode))
    188. {
    189. sprintf(buf+strlen(buf),
    190. "
    191. ",name,name,st.st_size);
    192. }
    193. else
    194. {
    195. sprintf(buf+strlen(buf),
    196. "
    197. ",name,name,st.st_size);
    198. }
    199. //printf("cfd:%d Sendbuf[%s]\n",cfd,buf);
    200. //send(cfd,buf,strlen(buf),0);
    201. bufferevent_write(event,buf,strlen(buf));
    202. memset(buf,0,sizeof(buf));
    203. free(namelist[i]);
    204. }
    205. sprintf(buf,"
    206. %s%ld
      %s%ld
      "
      );
    207. //printf("cfd:%d Sendbuf[%s]\n",cfd,buf);
    208. //send(cfd,buf,strlen(buf),0);
    209. bufferevent_write(event,buf,strlen(buf));
    210. free(namelist);
    211. return 0;
    212. }
    213. int SendFile(struct bufferevent *event,const char* filename)
    214. {
    215. int fd = open(filename,O_RDONLY);
    216. if(fd >0)
    217. {
    218. #if 1
    219. while(1)
    220. {
    221. char buf[1024];
    222. int len = read(fd,buf,sizeof buf);
    223. if(len >0)
    224. {
    225. //send(cfd,buf,len,0);
    226. bufferevent_write(event,buf,len);
    227. usleep(10);
    228. }
    229. else if(len == 0)
    230. {
    231. printf("Read file end\n");
    232. break;
    233. }
    234. else
    235. {
    236. perror("read error");
    237. }
    238. }
    239. #else
    240. off_t offset = 0;
    241. int file_size = lseek(fd,0,SEEK_END);
    242. lseek(fd,0,SEEK_SET);
    243. while(offset
    244. {
    245. int send_len = sendfile(cfd,fd,&offset,file_size-offset);
    246. if(send_len == -1)
    247. {
    248. if(errno == EAGAIN)
    249. {
    250. //perror("sendfile no data send");
    251. }
    252. else
    253. {
    254. perror("sendfile ret -1");
    255. }
    256. }
    257. else
    258. {
    259. printf("Send len:%d\n",send_len);
    260. }
    261. }
    262. #endif
    263. }
    264. else
    265. {
    266. perror("open file failed");
    267. }
    268. close(fd);
    269. return 0;
    270. }
    271. int http_request(struct bufferevent *event,char *path)
    272. {
    273. char *file = NULL;
    274. if(strcmp(path,"/") == 0)
    275. {
    276. file = "./";
    277. }
    278. else
    279. {
    280. file = path+1;
    281. }
    282. struct stat st;
    283. int ret = stat(file,&st);
    284. if(ret == -1)
    285. {
    286. printf("file doest not exist\n");
    287. SendHead(event,404,"Not found",GetFileType(".html"),-1);
    288. SendFile(event,"404.html");
    289. return -1;
    290. }
    291. if(S_ISDIR(st.st_mode))
    292. {
    293. printf("Directory\n");
    294. SendHead(event,200,"OK",GetFileType(".html"),-1);
    295. SendDir(event,file);
    296. }
    297. else
    298. {
    299. printf("File\n");
    300. SendHead(event,200,"OK",GetFileType(file),st.st_size);
    301. SendFile(event,file);
    302. }
    303. return 0;
    304. }
    305. void read_cb(struct bufferevent *event,void *arg)
    306. {
    307. char buf[256] = {0};
    308. char method[10]= {0},path[256]={0},protocol[10]={0};
    309. int ret = bufferevent_read(event,buf,sizeof(buf));
    310. if(ret >0)
    311. {
    312. sscanf(buf,"%[^ ] %[^ ] %[^ \r\n]",method,path,protocol);
    313. if(strcasecmp(method,"get") == 0)
    314. {
    315. char bufline[256] = {0};
    316. write(STDOUT_FILENO,buf,ret);
    317. while((ret = bufferevent_read(event,bufline,sizeof(bufline)))>0)
    318. {
    319. write(STDOUT_FILENO,bufline,ret);
    320. }
    321. http_request(event,path);
    322. }
    323. }
    324. }
    325. void bevent_cb(struct bufferevent *event,short what,void *arg)
    326. {
    327. if(what & BEV_EVENT_EOF)
    328. {
    329. printf("client closeed\n");
    330. bufferevent_free(event);
    331. }
    332. else if(what & BEV_EVENT_ERROR)
    333. {
    334. printf("client error\n");
    335. bufferevent_free(event);
    336. }
    337. else if(what & BEV_EVENT_CONNECTED)
    338. {
    339. printf("new client connected\n");
    340. }
    341. }
    342. void listener_cb(struct evconnlistener *listener,evutil_socket_t fd,struct sockaddr *addr,int socklen,void *arg)
    343. {
    344. struct event_base *base = (struct event_base*)arg;
    345. struct bufferevent *event= bufferevent_socket_new(base,fd,BEV_OPT_CLOSE_ON_FREE);
    346. bufferevent_setcb(event,read_cb,NULL,bevent_cb,base);
    347. bufferevent_enable(event,EV_READ|EV_WRITE);
    348. }
    349. int main (int argc ,char*argv[])
    350. {
    351. signal(SIGINT, sig_handler);
    352. signal(SIGTERM, sig_handler);
    353. signal(SIGKILL, sig_handler);//Program can not recieve SIGKILL(9) signal so.... this cmd does not make any sense
    354. // Ignore broken pipes
    355. signal(SIGPIPE, SIG_IGN);
    356. char work_dir[256]={0};
    357. strcpy(work_dir,getenv("PWD"));
    358. printf("dir:%s\n",work_dir);
    359. chdir(work_dir);
    360. struct event_base *base = event_base_new();
    361. struct sockaddr_in server;
    362. server.sin_family = AF_INET;
    363. server.sin_port = htons(9999);
    364. server.sin_addr.s_addr = htonl(INADDR_ANY);
    365. struct evconnlistener *listener = evconnlistener_new_bind(base,listener_cb,base,
    366. LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE_PORT,-1,
    367. (struct sockaddr *)&server,sizeof(server));
    368. event_base_dispatch(base);
    369. event_base_free(base);
    370. evconnlistener_free(listener);
    371. printf("Exit normally\n");
    372. return 0;
    373. }

  • 相关阅读:
    Linux安装与卸载Jenkins
    Java版正则表达式实现
    C语言内功修炼--指针详讲(进阶)
    Websocket升级版
    解读云视商系统开发等主流9大电商APP商业模式
    学习笔记-关于过滤\<\?php标签这件事
    【.NET8】访问私有成员新姿势UnsafeAccessor(上)
    深入理解Linux进程管理与优化:原理、调度和资源控制详解
    GO学习之 远程过程调用(RPC)
    动画详解常用排序算法(1)
  • 原文地址:https://blog.csdn.net/baoecit/article/details/133445242