改进的多线程服务器与客户端,这样服务器只用一个进程就可以对多个客户端提供服务了。
服务器:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
#define MAXLINE 4096
#define SERV_PORT 9877
#define SA struct sockaddr
#define LISTENQ 1024
void sig_chld(int signo);
void *run();
int connfd;
pthread_t tid;
char buf[MAXLINE];
int
main(int argc, char **argv)
{
int listenfd;
ssize_t n;
pid_t pid;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
listen(listenfd, LISTENQ);
signal(SIGCHLD, sig_chld);
while(1){
clilen = sizeof(cliaddr);
connfd = accept(listenfd, (SA *) &cliaddr, &clilen);
pthread_create(&tid, NULL, run, NULL);
}
}
void
sig_chld(int signo)
{
pid_t pid;
int stat;
while((pid = waitpid(-1, &stat, WNOHANG)) > 0)
printf("child %d terminated/n", pid);
return;
}
void* run()
{
ssize_t ret;
pthread_detach(tid);
int pconnfd;
pconnfd = connfd;
while(1)
{
if((ret = read(pconnfd, buf, MAXLINE)) == 0)
break;
ret = write(pconnfd,buf,ret);
}
return NULL;
}
客户端:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#define BUFFSIZE 4096
#define SERV_PORT 9877
#define SA struct sockaddr
#define LISTENQ 1024
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
void str_cli(FILE *fp, int sockfd);
void* psend();
pthread_t tid;
int sockfd;
char buf[BUFFSIZE];
//struct timeval tpstart,tpend;
double timeuse;
int tffd;
char tcount[64];
int
main(int argc, char **argv)
{
ssize_t n;
struct sockaddr_in servaddr;
if(argc != 2){
printf("usage: cmd <IPaddress>/n");
exit(0);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
if(connect(sockfd, (SA *) &servaddr, sizeof(servaddr))==-1)
{
printf("connect failed!/n");
exit(0);
}
pthread_create(&tid, NULL, psend, NULL);
while(1)
{
if((n = read(sockfd, buf, BUFFSIZE)) == 0)
break;
n = write(STDOUT_FILENO,buf,n);
}
exit(0);
}
void* psend()
{
ssize_t ret;
pthread_detach(tid);
int psockfd;
psockfd = sockfd;
struct timeval tpstart,tpend;
gettimeofday(&tpstart,NULL);
while(1)
{
if((ret = read(STDIN_FILENO,buf,BUFFSIZE)) == 0)
break;
ret = write(psockfd, buf, ret);
}
gettimeofday(&tpend,NULL);
timeuse=1000000*(tpend.tv_sec-tpstart.tv_sec)+tpend.tv_usec-tpstart.tv_usec;
timeuse/=1000000;
gcvt(timeuse, 10, tcount);
tffd = open("time.txt",O_RDWR|O_APPEND|O_CREAT, 0644);
write(tffd, tcount, 64);
close(tffd);
close(psockfd);
return NULL;
}