服务器大致流程图
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <errno.h>
#define SERV_PORT 8000
#define MAXLINE 8192
#define INET_ADDRSTRLEN 16
struct s_info
{
struct sockaddr_in clitaddr; //客户端地址
int connfd; //客户端fd
};
//子线程 回调函数
void *do_work(void *arg) //读数据 , 小 -> 大
{
struct s_info *ts = (struct s_info *)arg;
char buf[MAXLINE];
int ret;
char str[INET_ADDRSTRLEN];
while(1)
{
ret = read(ts->connfd, buf, MAXLINE);
if(ret == 0)
{
printf("the client %d close--\n", ts.connfd);
break; //跳出while 再关闭 客户端
}
printf("receiced from %s at PORT %d\n",
inet_ntop(AF_INET, &(*ts).clitaddr.sin_addr.s_addr, str, sizeof(str)),
ntohs(&( *ts).clitaddr.sin_port));
//小 ——》大
for(i = 0; i < ret; i++)
{
buf[i] = toupper(buf[i]);
}
write(ts->connfd, buf, ret);
write(STDOUT_FILENO, buf, ret);
}
close(ts->connfd);
return (void *)0;
}
int main(int argc, char *argv[])
{
struct sockaddr_in servaddr, clitaddr; //创建客户端与服务器 地址
socklen_t clitaddr_len; //定义客户端地址长度(传入传出参数必须定义变量)
int listenfd, connfd;
pthread_t = tid; //定义子线程
struct s_info ts[256];
int i = 0;
listenfd = socket(AF_INET, SOCK_STREAM, 0); //创建监听socket
bzero(&servaddr, sizeof(servaddr)); //清空服务器地址
servaddr.sin_family = AF_INET; //初始化服务器地址
servaddr.sin_port = htons(SERV_PORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(listenfd, 128);
prinf("accept client connect --\n");
while(1) //循环监听客户端连接
{
clitaddr_len = sizeof(clitaddr);
connfd = accept(listenfd, (struct sockaddr *)&clitaddr, clitaddr_len);
//将客服端 fd 地址放到 ts 中
ts[i].clitaddr = clitaddr;
ts[i].connfd = connfd;
//调用子线程 处理
pthread_create(&tid, NULL, do_work, ts[i]);
pthread_detach(tid);
i++;
}
return 0;
}