Web服务器1-socket编程

Web服务器1-socket编程
time服务器的客户端服务器,提交程序运行截图
代码

csapp.c

include <netinet/in.h>

include <arpa/inet.h>

include <netdb.h>

include <sys/types.h>

include <sys/socket.h>

include <stdlib.h>

include <string.h>

include <errno.h>

include <stdio.h>

define MAXLINE 100

typedef struct sockaddr SA;

define LISTENQ 1024

define EINTR 4

define RIO_BUFSIZE 8192

typedef struct{
int rio_fd;
int rio_cnt;
char rio_bufptr;
char rio_buf[RIO_BUFSIZE];
}rio_t;
int open_listenfd(int port){
int listenfd,optval=1;
struct sockaddr_in serveraddr;
if((listenfd = socket(AF_INET,SOCK_STREAM,0))<0)
return -1;
if(setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,
(const void
)&optval,sizeof(int))<0)
return -1;
bzero((char )&serveraddr,sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons((unsigned short)port);
if(bind(listenfd,(SA
)&serveraddr,sizeof(serveraddr))<0)
return -1;
if(listen(listenfd,LISTENQ)<0)
return -1;
return listenfd;
}
int open_clientfd(char *hostname,int port){
int clientfd;
struct hostent *hp;
struct sockaddr_in serveraddr;
if((clientfd = socket(AF_INET,SOCK_STREAM,0))<0)
return -1;
if((hp = gethostbyname(hostname))NULL)
return -2;
bzero((char *)&serveraddr,sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
bcopy((char *)hp->h_addr_list[0],
(char *)&serveraddr.sin_addr.s_addr,hp->h_length);
serveraddr.sin_port = htons(port);
if(connect(clientfd,(SA *)&serveraddr,sizeof(serveraddr))<0)
return -1;
return clientfd;
}
ssize_t rio_writen(int fd, void *usrbuf,size_t n){
size_t nleft = n;
ssize_t nwritten;
char *bufp = usrbuf;
while(nleft>0){
if((nwritten = write(fd,bufp,nleft))<=0){
if((nwritten = write(fd,bufp,nleft))<=0){
if(errno == EINTR)
nwritten = 0;
else
return -1;
}
nleft -= nwritten;
bufp += nwritten;
}
}
return n;
}
void rio_readinitb(rio_t *rp,int fd){
rp->rio_fd = fd;
rp->rio_cnt = 0;
rp->rio_bufptr = rp->rio_buf;
}
ssize_t rio_read(rio_t *rp,char *usrbuf,size_t n){
int cnt;
while(rp->rio_cnt <=0){
rp->rio_cnt = read(rp->rio_fd,rp->rio_buf,sizeof(rp->rio_buf));
if(rp->rio_cnt<0){
if(errno!=EINTR)
return -1;
}
else if(rp->rio_cnt
0)
return 0;
else
rp->rio_bufptr = rp->rio_buf;
}
cnt = n;
if(rp->rio_cnt < n)
cnt = rp->rio_cnt;
memcpy(usrbuf,rp->rio_bufptr,cnt);
rp->rio_bufptr += cnt;
rp->rio_cnt -= cnt;
return cnt;
}
ssize_t rio_readlineb(rio_t *rp,void usrbuf,size_t maxlen){
int n,rc;
char c,
bufp = usrbuf;
for(n=1;n<maxlen;n++){
if((rc = rio_read(rp,&c,1))1){
*bufp++ = c;
if(c
'\n')
break;
}else if(rc0){
if(n
1)
return 0;
else
break;
}else
return -1;
}
*bufp = 0;
return n;
}
void echo(int connfd){
size_t n;
char buf[MAXLINE];
rio_t rio;
rio_readinitb(&rio,connfd);
while((n = rio_readlineb(&rio,buf,MAXLINE))!=0){
printf("server received %d bytes\n",n);
rio_writen(connfd,buf,n);
}
}

dateclient.c

include <stdio.h>

include <netinet/in.h>

include <arpa/inet.h>

include <netdb.h>

include <sys/types.h>

include <sys/socket.h>

include <stdlib.h>

include <string.h>

define RIO_BUFSIZE 8192

typedef struct{
int rio_fd;
int rio_cnt;
char *rio_bufptr;
char rio_buf[RIO_BUFSIZE];
}rio_t;

define MAXLINE 200

int main(int argc,char **argv){
int clientfd,port;
char *host,buf[MAXLINE];
char sbuf[MAXLINE];
char rbuf[MAXLINE];
rio_t rio;
char str1[MAXLINE]="客户端IP:";
char str2[MAXLINE]="服务器实现者学号:20201331";
char str3[MAXLINE]="当地时间:";
if(argc!=3){
fprintf(stderr,"usage:%s \n",argv[0]);
exit(0);
}
host = argv[1];
port = atoi(argv[2]);
clientfd = open_clientfd(host,port);
while(1){
recv(clientfd,rbuf,MAXLINE,0);
printf("%s",str1);
puts(host);
printf("%s",str2);
putchar('\n');
printf("%s",str3);
puts(rbuf);
close(clientfd);
exit(0);
}
}

dateserve.c

include <stdio.h>

include <unistd.h>

include <netinet/in.h>

include <arpa/inet.h>

include <netdb.h>

include <sys/wait.h>

include <sys/types.h>

include <sys/socket.h>

include <stdlib.h>

include <time.h>

include <string.h>

define MAXLINE 200

define RIO_BUFSIZE 8192

typedef struct{
int rio_fd;
int rio_cnt;
char *rio_bufptr;
char rio_buf[RIO_BUFSIZE];
}rio_t;
typedef struct sockaddr SA;
typedef struct{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
}tm;
void sigchld_handler(int sig){
pid_t pid;
int stat;
while((pid = waitpid(-1,&stat,WNOHANG))>0){
printf("child %d terminated\n",pid);
}
return;
}
int main(int argc,char **argv){
int listenfd,connfd,port,clientlen;
struct sockaddr_in clientaddr;
struct hostent *hp;
char *haddrp;
char sbuf[MAXLINE];
char rbuf[MAXLINE];
rio_t rio;
time_t lt;
tm *local;
char str1[MAXLINE]="客户端IP:";
char str2[MAXLINE]="服务器实现者学号:";
char str3[MAXLINE]="当地时间:";
if(argc != 2){
fprintf(stderr,"usage:%s \n",argv[0]);
exit(0); }
port = atoi(argv[1]);
signal(SIGCHLD,sigchld_handler);
listenfd = open_listenfd(port);
while(1){
clientlen = sizeof(clientaddr);
connfd = accept(listenfd,(SA )&clientaddr,&clientlen);
hp = gethostbyaddr((const char
)&clientaddr.sin_addr.s_addr,
sizeof(clientaddr.sin_addr.s_addr),AF_INET);
haddrp = inet_ntoa(clientaddr.sin_addr);
printf("server connected to %s (%s)\n",hp->h_name,haddrp);
if(fork() == 0){
close(listenfd);
lt = time(NULL);
local = localtime(&lt);
strftime(sbuf,64,"%Y-%m-%d %H:%M:%S",local);
send(connfd,sbuf,MAXLINE,0);
close(connfd);
exit(0);
}
close(connfd);
}
}

运行结果

Client


server

echo服务器的客户端服务器,提交程序运行截图,服务器把客户端传进来的内容加入“服务器进程pid 你的学号 姓名 echo :”返回给客户端
代码

echoclient.C

include <stdio.h>

include <netinet/in.h>

include <arpa/inet.h>

include <netdb.h>

include <sys/types.h>

include <sys/socket.h>

include <stdlib.h>

include <string.h>

define RIO_BUFSIZE 8192

typedef struct{
int rio_fd;
int rio_cnt;
char *rio_bufptr;
char rio_buf[RIO_BUFSIZE];
}rio_t;

define MAXLINE 200

int main(int argc,char **argv){
int clientfd,port;
char *host,buf[MAXLINE];
char sbuf[MAXLINE];
char rbuf[MAXLINE];
rio_t rio;
char str1[MAXLINE]="服务器进程pid:";
char str2[MAXLINE]="服务器实现者学号姓名:20201331 hwg";
char str3[MAXLINE]="echo:";
if(argc!=3){
fprintf(stderr,"usage:%s \n",argv[0]);
exit(0);
}
host = argv[1];
port = atoi(argv[2]);
clientfd = open_clientfd(host,port);
while(1){
scanf("%[^\n]",sbuf);
send(clientfd,sbuf,MAXLINE,0);
recv(clientfd,rbuf,MAXLINE,0);
printf("%s",str1);
printf("%d\n",getpid());
printf("%s",str2);
putchar('\n');
printf("%s",str3);
puts(rbuf);
close(clientfd);
exit(0);
}
}

echoserver.c

include <stdio.h>

include <unistd.h>

include <netinet/in.h>

include <arpa/inet.h>

include <netdb.h>

include <sys/wait.h>

include <sys/types.h>

include <sys/socket.h>

include <stdlib.h>

include <time.h>

include <string.h>

include <pthread.h>

define MAXLINE 200

define RIO_BUFSIZE 8192

typedef struct{
int rio_fd;
int rio_cnt;
char *rio_bufptr;
char rio_buf[RIO_BUFSIZE];
}rio_t;
typedef struct sockaddr SA;
typedef struct{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
}tm;
void *thread(void vargp);
int main(int argc,char **argv){
int listenfd,
connfdp,port;
int clientlen;
struct sockaddr_in clientaddr;
struct hostent *hp;
char *haddrp;
pthread_t tid;
if(argc != 2){
fprintf(stderr,"usage:%s \n",argv[0]);
exit(0);
}
port = atoi(argv[1]);
listenfd = open_listenfd(port);
while(1){
clientlen = sizeof(clientaddr);
connfdp =malloc(sizeof(int));
*connfdp = accept(listenfd,(SA )&clientaddr,&clientlen);
hp = gethostbyaddr((const char
)&clientaddr.sin_addr.s_addr,
sizeof(clientaddr.sin_addr.s_addr),AF_INET);
haddrp = inet_ntoa(clientaddr.sin_addr);
printf("server connected to %s (%s)\n",hp->h_name,haddrp);
pthread_create(&tid,NULL,thread,connfdp);
pthread_join(tid,NULL);
}
}
void *thread(void *vargp){
time_t lt;
tm *local;
char sbuf[MAXLINE];
char rbuf[MAXLINE];
int connfd = ((int)vargp);
free(vargp);
pthread_detach(pthread_self());
recv(connfd,rbuf,MAXLINE,0);
printf("The massage is :%s\n",rbuf);
send(connfd,rbuf,MAXLINE,0);
close(connfd);
return NULL;
}

运行结果

echoclient

echoserver

服务器部署到华为云服务器,客户端用Ubuntu虚拟机。

client端

Server端

要用多线程或者多进程实现,至少连接两个客户端

两个客户端


-server端

posted @ 2022-12-01 17:01  常仁  阅读(18)  评论(0编辑  收藏  举报