#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>
#include<errno.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<string.h>
#include<signal.h>
#define ERR_EXIT(m) do{perror(m);exit(EXIT_FAILURE);}while (0)
#define LENGTH_OF_LISTEN_QUEUE 20
#define BUFFER_SIZE 1000
//pthread_metux_t mlock = PTHREAD_METUX_INITIALIZER;
int main(void)
{
int servfd;
struct sockaddr_in servaddr;
void *doit(void *);
if ((servfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
//建立Socket,程序调用Socket函数,该函数返回一个类似于文件描述符的句柄
printf("create socket error!\n");
exit(1);
}
//sin_zero用来将sockaddr_in结构填充到与struct sockaddr同样的长度,可以用bzero()或memset()函数将其置为零
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9999);
servaddr.sin_addr.s_addr = htons(INADDR_ANY);/*系统自动填入本机IP地址 */
int on =1;
if(setsockopt(servfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
ERR_EXIT("setsockopt error");
if (bind(servfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
{
//服务端通过调用 bind函数来配置本地信息。Bind函数将socket与本机上的一个端口相关联,随后你就可以在该端口监听服务请求。
printf("bind to port %d failure!\n",9999);
exit(1);
}
if (listen(servfd, LENGTH_OF_LISTEN_QUEUE) < 0)
{
//Listen函数使socket处于被动的监听模式,并为该socket建立一个输入数据队列,将到达的服务请求保存在此队列中,直到程序处理它们。
printf("call listen failure!\n");
exit(1);
}
struct sockaddr_in cliaddr;
socklen_t clilen = sizeof(cliaddr);//
//cliaddr = Malloc(clilen);//为保留客户端address开辟空间
int clientfd;
while(1)
{
//服务一直在运行,直到被某个操作或命令终止该进程
//accept()函数让服务器接收客户的连接请求
if((clientfd = accept(servfd, (struct sockaddr *)&cliaddr, &clilen)) < 0)
{
if(errno == EINTR)
continue;
else
ERR_EXIT("accept error");
}
printf("recv connect ip = %s port = %d\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
// 创建用于处理新连接的子线程
pthread_t tid ; //
pthread_create(&tid, NULL, &doit, (void*)clientfd);
}
}
void* doit (void* arg)
{
// 分离线程,使主线程不必等待此线程
pthread_detach(pthread_self());
int recvBytes = 0;
char recvBuf[BUFFER_SIZE];
while(1)
{
memset(recvBuf, 0, BUFFER_SIZE);
if ((recvBytes=recv((int) arg, recvBuf, BUFFER_SIZE, 0)) <= 0)
{
perror("recv出错!\n");
return NULL;
}
recvBuf[recvBytes]='\0';
printf("recvBuf:%s\n", recvBuf);
send((int) arg, recvBuf, sizeof(recvBuf), 0);
}
close((int) arg);
return NULL;
}