首页 > 其他分享 >web实验1-socket

web实验1-socket

时间:2022-12-01 18:12:38浏览次数:42  
标签:web MAXLINE socket int char rio tm 实验 include

基于华为鲲鹏云服务器CentOS中(或Ubuntu),使用Linux Socket实现:

1. time服务器的客户端服务器,提交程序运行截图

timeserver代码

#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 <port>\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);
      }
}

csapp代码

#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(rc==0){
        
            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);
    }
}

timeclient代码

#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]="服务器实现者学号:20201305焦腾辉";
    
    char str3[MAXLINE]="当地时间:";

    if(argc!=3){
    
        fprintf(stderr,"usage:%s <host> <port>\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);
    }
}

实现截图

image
image

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

echoserver代码

#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 <port>\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代码

#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]="服务器实现者学号姓名:20201305 jth";
    
    char str3[MAXLINE]="echo:";

    if(argc!=3){
    
        fprintf(stderr,"usage:%s <host> <port>\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);
    }

}

截图

image
image
image

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

实验截图

image
image

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

server代码

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<pthread.h>
 
void* communication(void* arg);
 
int main()
{
 int sockfd=socket(PF_INET,SOCK_STREAM,0);
 assert(-1!=sockfd);
 
 struct sockaddr_in ser,cli;
 ser.sin_family=AF_INET;
 ser.sin_port=htons(6000);
 ser.sin_addr.s_addr=inet_addr("127.0.0.1");
 int res=bind(sockfd,(struct sockaddr*)&ser,sizeof(ser));
 assert(-1!=res);
 
 listen(sockfd,5);
 
 while(1)
 {
  int len=sizeof(cli);
  int c=accept(sockfd,(struct sockaddr*)&cli,&len);
        if(c<0)
        {
            printf("link error\n");
            continue;
        }
 
  pthread_t id;
  int n=pthread_create(&id,NULL,communication,(void*)c);
  assert(n==0);
 }
    close(sockfd);
}
 
void* communication(void* arg)
{
 while(1)
 {
     char buff[128]={0};
     int c=(int)arg;
     int n=recv(c,buff,127,0);
     if(n<=0)
     {
   close(c);
   printf("%d client over\n",c);
   break;
     }
     printf("%d:%s\n",c,buff);
 
  send(c,"OK",2,0);
 }
}

client代码

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<netinet/in.h>
 
int main()
{
 int sockfd = socket(PF_INET,SOCK_STREAM,0);
 assert(-1!=sockfd);
 
 struct sockaddr_in ser,cli;
 memset(&ser,0,sizeof(ser));
 ser.sin_family=AF_INET;
 ser.sin_port=htons(6000);
 ser.sin_addr.s_addr=inet_addr("127.0.0.1");
 int res=connect(sockfd,(struct sockaddr*)&ser,sizeof(ser));
 assert(res!=-1);
 
 while(1)
 {
  printf("Please input:");
  fflush(stdout);
  char buff[128]={0};
  fgets(buff,127,stdin);
  buff[strlen(buff)-1]=0;
 
  if(strncmp(buff,"end",3)==0)
  {
      break;
  }
  send(sockfd,buff,strlen(buff),0);
 
  memset(buff,0,sizeof(buff));
  recv(sockfd,buff,127,0);
  printf("%s\n",buff);
 }
 close(sockfd);
}

实验截图

image

5. 把服务器部署到试验箱。(加分项)

标签:web,MAXLINE,socket,int,char,rio,tm,实验,include
From: https://www.cnblogs.com/1395372955jth/p/16942233.html

相关文章

  • 实验六
    实验四#include<iostream>#include<cassert>usingstd::cout;usingstd::endl;template<classT>classVector{public:Vector(intn,intm);Vector(i......
  • 实验六
    TASK3:int:char: char和int的的字节数不一样,int占一个字节数,插入占4个,改为char后,按4个数据写入,则写入了97“ 空格”“空格”“ 空格”“空格”,然后写入98,在写......
  • 实验四 Web服务器1-socket编程
    任务详情基于华为鲲鹏云服务器CentOS中(或Ubuntu),使用LinuxSocket实现:time服务器的客户端服务器,提交程序运行截图echo服务器的客户端服务器,提交程序运行截图,服务器把客......
  • web服务器2
    编译查看ip地址访问服务器部署到华为云服务器,浏览器用本机的服务器部署访问......
  • 实验6-模板类和文件
    task3:task3.1.cpp1#include<iostream>2#include<fstream>3#include<array>4#defineN55intmain()6{7usingnamespacestd;8array<int......
  • Web服务器2
    ......
  • WEB-RTC 基础概念和架构
    参考文章:WebRTC简介;从0搭建一个WebRTC,实现多房间多对多通话,并实现屏幕录制;架构:经典三层结构:Webapp层(应用层):Web开发者开发的程序,Web开发者可以基于集成Web......
  • sdwebimage的使用
    WebImageThislibraryprovidesacategoryforUIImageVIewwithsupportforremoteimagescomingfromtheweb.Itprovides:AnUIImageViewcategoryaddingwebimag......
  • 网络渗透测试实验_1_网络扫描与网络侦察
    以下内容为课堂上的实验记录1. 实验目的和要求理解网络扫描、网络侦察的作用;通过搭建网络渗透测试平台,了解并熟悉常用搜索引擎、扫描工具的应用,通过信息收集为下一步渗......
  • 实验六
    1#include<iostream>2#include<fstream>3#include<array>4#defineN556intmain(){7usingnamespacestd;8array<char,N>x;91......