zoukankan      html  css  js  c++  java
  • 和菜鸟一起深入学习国嵌实验之网络编程

    1、 tcp程序设计

    代码1 server:

    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    #include <netdb.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
     
    #define portnumber 3333
     
    int main(int argc, char *argv[])
    {
       int sockfd, new_fd;
       struct sockaddr_in server_addr;
       struct sockaddr_in client_addr;
       int sin_size;
       int nbytes;
       char buffer[1024];
       
       //AF_INET: IPV4, SOCK_STREAM: TCP
       if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        {
            fprintf(stderr, "Socket error:%s\n\a", strerror(errno));
           exit(1);
        }
     
       bzero(&server_addr, sizeof(struct sockaddr_in));
       server_addr.sin_family = AF_INET;
       server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
       server_addr.sin_port = htons(portnumber);
     
       if(bind(sockfd, (struct sockaddr *) (&server_addr), sizeof(structsockaddr)) == -1)
        {
           fprintf(stderr, "Bind error: %s\n\a", strerror(errno));
           exit(1);
        }
     
       if(listen(sockfd, 5) == -1)
        {
           fprintf(stderr, "Listen error: %s\n\a", strerror(errno));
           exit(1);        
        }
     
     
       while(1)
        {
           sin_size = sizeof(struct sockaddr_in);
           if((new_fd = accept(sockfd, (struct sockaddr *)(&client_addr),&sin_size)) == -1)
           {
                fprintf(stderr, "Accept error:%s\n\a", strerror(errno));
               exit(1);
           }
     
           fprintf(stderr, "Server get connection from %s\n",(char*)inet_ntoa(client_addr.sin_addr));
     
           if((nbytes = read(new_fd, buffer, 1024)) == -1)
            {
               fprintf(stderr, "Read Error: %s\n", strerror(errno));
               exit(1);
           }
     
           buffer[nbytes] = '\0';
     
           printf("Server received %s\n", buffer);
     
           close(new_fd);
        }
     
       close(sockfd);
       
       return 0;
    }


    代码2 client:

    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    #include <netdb.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
     
    #define portnumber 3333
     
    int main(int argc, char *argv[])
    {
       int sockfd;
       char buffer[1024];
       struct sockaddr_in server_addr;
       struct hostent *host;
     
       if(argc != 2)
        {
           fprintf(stderr, "Usage: %s hostname \a\n", argv[0]);
           exit(1);
        }
     
       if((host = gethostbyname(argv[1])) == NULL)
        {
            fprintf(stderr, "Gethostname Error:%s\a\n", strerror(errno));
           exit(1);
        }
     
       if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        {
           fprintf(stderr, "Socket Error: %s\a\n", strerror(errno));
           exit(1);
        }
     
     
       bzero(&server_addr, sizeof(server_addr));
       server_addr.sin_family = AF_INET;
       server_addr.sin_port = htons(portnumber);
       server_addr.sin_addr = *((struct in_addr *) host->h_addr);
     
       if(connect(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr))== -1)
        {
           fprintf(stderr, "Connect Error: %s\a\n", strerror(errno));
           exit(1);
        }
     
       printf("Please input char: \n");
     
       fgets(buffer, 1024, stdin);
       write(sockfd, buffer, strlen(buffer));
     
       close(sockfd);
     
    return 0;
    }


    Makefile:

    CC = gcc
     
    CURTDIR = $(shell pwd)
    TARGET = tcp_client
    #TARGET = tcp_server
     
    %.o:%.c
           $(CC)-c $(EXTRAFLAGS) $< -o $@
    %.o:%.S
           $(CC)-c $(EXTRAFLAGS) $< -o $@
     
    .PHONY: all clean
     
    $(TARGET): $(TARGET).o
           $(CC)  -o $@ $^
     
    clean:
           rm-rf $(TARGET) $(TARGET).o


    运行结果:

    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.1$make
    gcc -c tcp_server.c -o tcp_server.o
    gcc -o tcp_server tcp_server.o
     
    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.1$ls
    Makefile tcp_client.c  tcp_server  tcp_server.c tcp_server.o
     
    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.1$make
    gcc -c tcp_client.c -o tcp_client.o
    gcc -o tcp_client tcp_client.o
     
    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.1$ls
    Makefile tcp_client  tcp_client.c  tcp_client.o tcp_server  tcp_server.c  tcp_server.o
     
     
    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.1$./tcp_client 192.0.4.87
    Please input char:
    hello mytcp
     
    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.1$./tcp_client 192.0.4.87
    Please input char:
    I am back!
     
    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.1$./tcp_server
    Server get connection from 192.0.4.87
    Server received hello mytcp
     
    Server get connection from 192.0.4.87
    Server received I am back!


    总结:当没有client连接上时,server程序阻塞在accept函数上,等待连接。当有client连接上来时,阻塞在read函数上,等待读取消息。Client发送一条消息后结束,server读出消息打印,继续等待新的连接

     

     

    2、 udp程序设计

    代码1 server:

    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    #include <netdb.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
     
    #define portnumber 3333
    #define MAX_MSG_SIZE 1024
     
    void udps_respon(int sockfd)
    {
       struct sockaddr_in addr;
       int addrlen, n;
       char msg[MAX_MSG_SIZE];
     
       while(1)
        {
           bzero(msg, sizeof(msg));
           addrlen = sizeof(struct sockaddr);
           n = recvfrom(sockfd, msg, MAX_MSG_SIZE, 0, (struct sockaddr *)&addr,&addrlen);
           msg[n] = 0;
           fprintf(stdout, "Server had received %s\n", msg);
        }
    }
     
    int main(int argc, char *argv[])
    {
       int sockfd;
       struct sockaddr_in addr;
       
       //AF_INET: IPV4, SOCK_DGRAM: UDP
       if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
        {
           fprintf(stderr, "Socket error: %s\n\a", strerror(errno));
           exit(1);
        }
     
       bzero(&addr, sizeof(struct sockaddr_in));
        addr.sin_family= AF_INET;
       addr.sin_addr.s_addr = htonl(INADDR_ANY);
       addr.sin_port = htons(portnumber);
     
       if(bind(sockfd, (struct sockaddr *) (&addr), sizeof(structsockaddr)) == -1)
        {
           fprintf(stderr, "Bind error: %s\n\a", strerror(errno));
           exit(1);
        }
     
       udps_respon(sockfd);
     
       close(sockfd);
          
       return 0;
    }


    代码2 client:

    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    #include <netdb.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
     
    #define portnumber 3333
    #define MAX_BUF_SIZE 1024
     
    void udpc_requ(int sockfd, const structsockaddr_in *addr, int len)
    {
       char buffer[MAX_BUF_SIZE];
       int n;
     
       while(1)
        {
           printf("Please input char: \n");
            fgets(buffer, MAX_BUF_SIZE, stdin);
           sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr*)addr, len);
           bzero(buffer, MAX_BUF_SIZE);
        }
    }
     
    int main(int argc, char *argv[])
    {
       int sockfd;
       struct sockaddr_in addr;
     
       if(argc != 2)
        {
           fprintf(stderr, "Usage: %s hostname \a\n", argv[0]);
           exit(1);
        }
     
       if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
        {
           fprintf(stderr, "Socket Error: %s\a\n", strerror(errno));
           exit(1);
        }
     
        bzero(&addr,sizeof(struct sockaddr_in));
       addr.sin_family = AF_INET;
       addr.sin_port = htons(portnumber);
       if(inet_aton(argv[1], &addr.sin_addr) < 0)
        {
           fprintf(stderr, "IP error:%s\n", strerror(errno));
           exit(1);
        }
      
       udpc_requ(sockfd, &addr, sizeof(struct sockaddr_in));
      
       close(sockfd);
     
    return 0;
    }


    Makefile:

    CC = gcc
     
    CURTDIR = $(shell pwd)
    TARGET = udp_client
    #TARGET = udp_server
     
    %.o:%.c
           $(CC)-c $(EXTRAFLAGS) $< -o $@
    %.o:%.S
           $(CC)-c $(EXTRAFLAGS) $< -o $@
     
    .PHONY: all clean
     
    $(TARGET): $(TARGET).o
           $(CC)  -o $@ $^
     
    clean:
           rm-rf $(TARGET) $(TARGET).o
     


    运行结果:

    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.2$make
    gcc -c udp_server.c -o udp_server.o
    gcc -o udp_server udp_server.o
     
    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.2$make
    gcc -c udp_client.c -o udp_client.o
    gcc -o udp_client udp_client.o
     
    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.2$./udp_client 192.0.4.87
    Please input char:
    hello myudp             
    Please input char:
    good-buy
    Please input char:
     
    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.2$./udp_server
    Server had received hello myudp
     
    Server had received good-buy
     

    总结:当没有client连接上时,server处于阻塞状态,阻塞在recvfrom函数上。当有client连接上来时。Client发送一条消息后结束,server读出消息打印。

     

     

    3、 并发服务器设计

    代码1 server:

    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    #include <netdb.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <pthread.h>
     
    #define portnumber 3333
     
    void *thr_fn(void *arg)
    {
       int size, j;
       char recv_buff[1024];
       int *parg = (int *)arg;
       int new_fd = *parg;
       
       printf("new_fd = %d\n", new_fd);
     
       while((size = read(new_fd, recv_buff, 1024)) > 0)
        {
           if(recv_buff[0] == '@')
               break;
           
           printf("Message from client(%d): %s\n", size, recv_buff);
           
           for(j = 0; j < size; j++)
           {
               recv_buff[j] = toupper(recv_buff[j]);
           }
           write(new_fd, recv_buff, size);
     
           memset(recv_buff, 0, sizeof(recv_buff));
        }
     
       close(new_fd);
     
       return NULL;
    }
     
    int main(int argc, char *argv[])
    {
       int listen_sockfd;
       int com_fd;
       int i;
       static char recv_buff[1024];
       int len;
       int port;
       pthread_t tid;
       socklen_t clt_addr_len;
     
       struct sockaddr_in server_addr;
       struct sockaddr_in client_addr;
      
       if(argc != 2)
        {
           printf("Usage: %s port\n", argv[0]);
           return 1;
        }
     
       port = atoi(argv[1]);
     
       if((listen_sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
        {
           fprintf(stderr, "Socket error: %s\n\a", strerror(errno));
           exit(1);
        }
     
       memset(&server_addr, 0, sizeof(server_addr));
       server_addr.sin_family = AF_INET;
       server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
       server_addr.sin_port = htons(port);
     
       if(bind(listen_sockfd, (struct sockaddr *) (&server_addr),sizeof(struct sockaddr)) == -1)
        {
           fprintf(stderr, "Bind error: %s\n\a", strerror(errno));
           close(listen_sockfd);
           exit(1);
        }
     
       if(listen(listen_sockfd, 5) == -1)
        {
           fprintf(stderr, "Listen error: %s\n\a", strerror(errno));
           close(listen_sockfd);
           exit(1);        
        }
     
       while(1)
        {
           len = sizeof(client_addr);
           com_fd = accept(listen_sockfd, (struct sockaddr*)&client_addr,&len);
           if(com_fd < 0)
           {
               if(errno == EINTR)
               {
                    continue;
               }
                else
               {
                    perror("cannot acceptclient connect request\n");
                    close(listen_sockfd);
                    return 1;
               }
           }
           printf("com_fd = %d\n", com_fd);
     
           if((pthread_create(&tid, NULL, thr_fn, &com_fd)) == -1)
           {
               perror("pthread_create error");
               close(listen_sockfd);
               close(com_fd);
               return 1;
           }
        }
     
       return 0;
    }


    代码2 client:

    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    #include <netdb.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <unistd.h>
    #include <sys/un.h>
     
    #define portnumber 3333
     
    int main(int argc, char *argv[])
    {
       int connect_fd;
       int ret;
       char snd_buf[1024];
       int i;
       int port;
       int len;
       static struct sockaddr_in server_addr;
     
       if(argc != 3)
        {
           fprintf(stderr, "Usage: %s ip \a\n", argv[0]);
           exit(1);
        }
     
       port = atoi(argv[2]);
     
       if((connect_fd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
        {
           fprintf(stderr, "Socket Error: %s\a\n", strerror(errno));
           exit(1);
        }
     
       bzero(&server_addr, sizeof(server_addr));
       server_addr.sin_family = AF_INET;
       server_addr.sin_addr.s_addr = inet_addr(argv[1]);
       server_addr.sin_port = htons(port);
     
       if(connect(connect_fd, (struct sockaddr *)(&server_addr),sizeof(struct sockaddr)) == -1)
        {
           fprintf(stderr, "Connect Error: %s\a\n", strerror(errno));
           exit(1);
        }
     
       memset(snd_buf, 0, 1024);
       
       while(1)
        {
           printf("input message: \n");
     
           memset(snd_buf, 0, sizeof(snd_buf));       
           fgets(snd_buf, 1024, stdin);
             
           len = strlen(snd_buf);
     
           write(connect_fd, snd_buf, len);
          
           len = read(connect_fd, snd_buf, len);
           if(len > 0)
               printf("Message from server: %s\n", snd_buf);
           if(snd_buf[0] == '@')
               break;
        }
       
       close(connect_fd);
     
    return 0;
    }

     

    Makefile:

    CC = gcc
     
    CURTDIR = $(shell pwd)
    #TARGET = thread_client
    TARGET = thread_server
     
    %.o:%.c
           $(CC)-c $(EXTRAFLAGS) $< -o $@
    %.o:%.S
           $(CC)-c $(EXTRAFLAGS) $< -o $@
     
    .PHONY: all clean
     
    $(TARGET): $(TARGET).o
           $(CC)  -o $@ $^ -lpthread
     
    clean:
           rm-rf $(TARGET) $(TARGET).o
     

     

    运行结果:

    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.3$make
    gcc -c thread_server.c -o thread_server.o
    gcc -o thread_server thread_server.o -lpthread
     
    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.3$ls
    Makefile thread_client.c thread_server thread_server.c  thread_server.o
     
     
    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.3$make
    gcc -c thread_client.c -o thread_client.o
    gcc -o thread_client thread_client.o -lpthread
     
    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.3$ls
    Makefile thread_client thread_client.c thread_client.o  thread_server  thread_server.c  thread_server.o
     
     
    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.3$./thread_client 192.0.4.87 2222
    input message:
    hello, i am the 1st
    Message from server: HELLO, I AM THE 1ST
     
    input message:
    @
    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.3$./thread_client 192.0.4.87 2222
    input message:
    hello, i am the 1st, i am back
    Message from server: HELLO, I AM THE 1ST, IAM BACK
     
    input message:
    @
     
     
    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.3$./thread_client 192.0.4.87 2222
    input message:
    hi, i am the 2nd
    Message from server: HI, I AM THE 2ND
     
    input message:
    @  
     
     
    eastmoon@eastmoon-virtual-machine:~/work/guoqian/4/4.3$./thread_server 2222
    com_fd = 4
    new_fd = 4
    Message from client(20): hello, i am the1st
     
    com_fd = 5
    new_fd = 5
    Message from client(17): hi, i am the 2nd
     
    com_fd = 6
    new_fd = 6
    Message from client(31): hello, i am the1st, i am back
     
    


           总结:并发服务器由于使用了多线程或者多进程,所以能同事接受多个客户端的连接。循环服务器只有在一个连接断掉之后才能接受另一个连接,因为服务器进程正在执行对客户端的消息收发不能继续循环去接受新的连接。

  • 相关阅读:
    03-spring bean
    04-spring的依赖注入
    01-课程安排
    17-注解开发
    WIN10新机必要设置记录 for 3dsmax
    ps导出svg
    VS C# 共享项目
    在Maxscript中创建.Net类型
    C# 自定义索引
    C# ?
  • 原文地址:https://www.cnblogs.com/wuyida/p/6300018.html
Copyright © 2011-2022 走看看