//server.c
#include"util.h"
#define SER_IP "127.0.0.1"
#define SER_PORT 6666
struct infor
{
struct sockaddr_in cliaddr;
int connfd;
};
void* thread_fun(void *arg)
{
char buf[BUFSIZ],str[INET_ADDRSTRLEN];//16
struct infor *var=(struct infor*)arg;
int i,n;
printf("Received from %s at port %d\n",
inet_ntop(AF_INET,&(var->cliaddr.sin_addr.s_addr),str,sizeof(str)),
ntohs(var->cliaddr.sin_port));
while(1)
{
n=Read(var->connfd,buf,sizeof(buf));
if(n==0)
{
printf("The Client %d closed!\n",var->connfd );
break;
}
else
{
for(i=0;i<n;i++)
buf[i]=toupper(buf[i]);
write(STDOUT_FILENO,buf,n);//写至屏幕
write(var->connfd,buf,n);//回写给客户端
}
}
close(var->connfd);
}
int main(int argc,char *argv[])
{
int listenfd,connfd;
int n,i=0;
pthread_t tid;
struct infor ts[128];
struct sockaddr_in serv_addr,cliaddr;
listenfd=start_up(SER_IP,SER_PORT);
printf("Accepting client connections.................\n ");
while(1)
{
socklen_t addrlen=sizeof(struct sockaddr);
connfd=Accept(listenfd,(struct sockaddr*)&cliaddr,&addrlen);
ts[i].cliaddr=cliaddr;
ts[i].connfd=connfd;
pthread_create(&tid,NULL,thread_fun,(void *)&ts[i]);
pthread_detach(tid);//子线程分离,防止僵线程产生
i++;
}
return 0;
}
/
util.h
#include<stdio.h>
#include<sys/socket.h>
#include<ctype.h>
#include<string.h>
#include<stdlib.h>
#include<arpa/inet.h>
#include<ctype.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>
#include<pthread.h>
#define SERPORT 6666
#define backlogs 10
void perr_exit(const char *s)
{
perror(s);
exit(1);
}
int Socket(int domain,int type,int protocol)
{
int fd=socket(domain,type,protocol);
if(fd==-1)
perr_exit("socket error!\n");
return fd;
}
int Bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen)
{
int ret=bind(sockfd,addr,addrlen);
if(ret==-1)
perr_exit("bind error!\n");
return ret;
}
int Listen(int sockfd,int backlog)
{
int ret=listen(sockfd,backlog);
if(ret==-1)
perr_exit("listen error!\n");
return ret;
}
int Accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen)//慢速系统调用
{
int ret;
again:
if( (ret=accept(sockfd,addr,addrlen)) ==-1)
{
if(errno==ECONNABORTED || errno==EINTR)
goto again;
else
perr_exit("accept error!\n");
}
return ret;
}
int start_up(const char* ip,int port)
{
int fd=Socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in ser_addr;
ser_addr.sin_family=AF_INET;
ser_addr.sin_port=htons(port);
ser_addr.sin_addr.s_addr=inet_addr(ip);
int on=1;
setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(int));
socklen_t addrlen=sizeof(struct sockaddr);
Bind(fd,(struct sockaddr*)&ser_addr,addrlen);
Listen(fd,backlogs);
return fd;
}
//connect() 不会阻塞
int Connect(int sockfd,const struct sockaddr *addr,socklen_t addrlen)
{
int ret;
ret=connect(sockfd,addr,addrlen);
if(ret==-1)
perr_exit("connect error!\n");
return ret;
}
ssize_t Read(int fd,void *buf,size_t nbytes)
{
ssize_t n;
again:
if( (n=read(fd,buf,nbytes))==-1)
{
if(errno==EINTR)
goto again;
else
perr_exit("read errror!\n");
}
return n;
}
ssize_t Write(int fd,void *buf,size_t nbytes)
{
ssize_t n;
again:
if( (n=write(fd,buf,nbytes))==-1)
{
if(errno==EINTR)
goto again;
else
perr_exit("write errror!\n");
}
return n;
}