1.socket 函数创建套接字 lfd
2.bind 绑定地址结构
3.listen 设置监听上限
while (1) {
cfd = Accept(lfd, );
pthread_create(&tid, NULL, tfn, (void *)cfd);//创建子线程
pthread_detach(tid); // pthead_join(tid, void **); 新线程---专用于回收子线程。
}
5. 子线程:
void *tfn(void *arg)
{
// close(lfd) 不能关闭。 主线程要使用lfd
read(cfd)
小--大
write(cfd)
pthread_exit((void *)10);
}
1.#include <stdio.h>
2.#include <string.h>
3.#include <arpa/inet.h>
4.#include <pthread.h>
5.#include <ctype.h>
6.#include <unistd.h>
7.#include <fcntl.h>
8.
9.#include "wrap.h"
10.
11.#define MAXLINE 8192
12.#define SERV_PORT 8000
13.
14.struct s_info { //定义一个结构体, 将地址结构跟cfd捆绑
15. struct sockaddr_in cliaddr;
16. int connfd;
17.};
18.
19.void *do_work(void *arg)
20.{
21. int n,i;
22. struct s_info *ts = (struct s_info*)arg;
23. char buf[MAXLINE];
24. char str[INET_ADDRSTRLEN]; //#define INET_ADDRSTRLEN 16 可用"[+d"查看
25.
26. while (1) {
27. n = Read(ts->connfd, buf, MAXLINE); //读客户端
28. if (n == 0) {
29. printf("the client %d closed...\n", ts->connfd);
30. break; //跳出循环,关闭cfd
31. }
32. printf("received from %s at PORT %d\n",
33. inet_ntop(AF_INET, &(*ts).cliaddr.sin_addr, str, sizeof(str)),
34. ntohs((*ts).cliaddr.sin_port)); //打印客户端信息(IP/PORT)
35.
36. for (i = 0; i < n; i++)
37. buf[i] = toupper(buf[i]); //小写-->大写
38.
39. Write(STDOUT_FILENO, buf, n); //写出至屏幕
40. Write(ts->connfd, buf, n); //回写给客户端
41. }
42. Close(ts->connfd);
43.
44. return (void *)0;
45.}
46.
47.int main(void)
48.{
49. struct sockaddr_in servaddr, cliaddr;
50. socklen_t cliaddr_len;
51. int listenfd, connfd;
52. pthread_t tid;
53.
54. struct s_info ts[256]; //创建结构体数组.
55. int i = 0;
56.
57. listenfd = Socket(AF_INET, SOCK_STREAM, 0); //创建一个socket, 得到lfd
58.
59. bzero(&servaddr, sizeof(servaddr)); //地址结构清零
60. servaddr.sin_family = AF_INET;
61. servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //指定本地任意IP
62. servaddr.sin_port = htons(SERV_PORT); //指定端口号
63.
64. Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); //绑定
65.
66. Listen(listenfd, 128); //设置同一时刻链接服务器上限数
67.
68. printf("Accepting client connect ...\n");
69.
70. while (1) {
71. cliaddr_len = sizeof(cliaddr);
72. connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len); //阻塞监听客户端链接请求
73. ts[i].cliaddr = cliaddr;
74. ts[i].connfd = connfd;
75.
76. pthread_create(&tid, NULL, do_work, (void*)&ts[i]);
77. pthread_detach(tid); //子线程分离,防止僵线程产生.
78. i++;
79. }
80.
81. return 0;
82.}