上机040

一,查看while源代码

1.scoket

  1. 原型:
    参数解释用法
    domain
    网络程序所在的主机采用的通讯协族(AF_UNIX和AF_INET等).AF_UNIX只能够用于单一的Unix 系统进程间通信,而AF_INET是针对Internet的,因而可以允许在远程主机之间通信(当我们 man socket时发现 domain可选项是 PF_而不是AF_,因为glibc是posix的实现所以用PF代替了AF,不过我们都可以使用的).
    ————————————————
    版权声明:本文为CSDN博主「Jie(11039)」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/m0_68755709/article/details/124257516
    type网络程序所采用的通讯协议(SOCK_STREAM,SOCK_DGRAM等)SOCK_STREAM表明使用的是TCP 协议,这样会提供按顺序的,可靠,双向,面向连接的比特流.SOCK_DGRAM 表明我们用的是UDP协议,这样只会提供定长的,不可靠,无连接的通信.
    protocol由于我们指定了type,所以这个地方我们一般只要用0来代替就可以了
    socket为网络通讯做基本的准备.成功时返回文件描述符,失败时返回-1,看errno可知道出错的详细情况

2.bind

  • 原型:

int bind(int sockfd, struct sockaddr *my_addr, int addrlen)

参数解释
sockfd由socket调用返回的文件描述符
addrlensockaddr结构的长度
my_addr一个指向sockaddr的指针. 在中有 sockaddr的定义
3.listen
  • 原型:
  • int listen(int sockfd,int backlog)
  • scokfd   是bind后的文件描述符
  • backiog  设置请求排队的最大长度.当有多个客户端程序和服务端相连时, 使用这个表示可以介绍的排队长度.
  • 4.accept

  • 原型
  • int accept(int sockfd, struct sockaddr *addr,int *addrlen)
  • scokfd
  • addr/addrlen是用来给客户端的程序填写的,服务器端只要传递指针就可以了

5.connect

int connect(int sockfd, struct sockaddr * serv_addr,int addrlen)

sockfdsocket返回的文件描述符
serv_addr储存了服务器端的连接信息.其中sin_add是服务端的地址
addrlenserv_addr的长度

二编译并在ubuntn下运行 

 
  • 代码

  • #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 <arpa/inet.h> 
     
    #define portnumber 3333
     
    int main(int argc, char* argv[]) {
        int local_listen_socket, server_session_socket;
        struct sockaddr_in server_addr_info_struct;
        struct sockaddr_in client_addr_info_struct;
        int size_of_sockaddr_in;
        int read_got_bytes_nr;
        char buffer[1024];
     
     
        /* socket: 服务器端开始建立sockfd描述符 */
        if ((local_listen_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) { // AF_INET i.e. IPV4; SOCK_STREAM i.e. TCP
            fprintf(stderr, "Socket error:%s\n\a", strerror(errno));
            exit(1);
        }
     
        /* 准备 sockaddr结构及其内部IP、端口信息 */
        bzero(&server_addr_info_struct, sizeof(struct sockaddr_in)); // 初始化,置0
        server_addr_info_struct.sin_family = AF_INET;                 // Internet
        server_addr_info_struct.sin_addr.s_addr = htonl(INADDR_ANY);  // 将本机host上的long数据转化为网络上的long数据,使服务器程序能运行在不同CPU的主机上 
                                                        // INADDR_ANY 表示主机监听任意/所有IP地址。
        //server_addr_info_struct.sin_addr.s_addr=inet_addr("192.168.1.1");  //用于绑定到一个固定IP,inet_addr用于把数字加格式的ip转化为整形ip
        server_addr_info_struct.sin_port = htons(portnumber);         // (将本机器上的short数据转化为网络上的short数据)端口号
     
        /* bind: 绑定sockfd描述符 和 IP、端口 */
        if (bind(local_listen_socket, (struct sockaddr*)(&server_addr_info_struct), sizeof(struct sockaddr)) == -1) {
            fprintf(stderr, "ERR bind():%s\n\a", strerror(errno));
            exit(1);
        }
     
        /* 设置允许连接的最大客户端数 */
        if (listen(local_listen_socket, 5) == -1) {
            fprintf(stderr, "ERR listen():%s\n\a", strerror(errno));
            exit(1);
        }
     
        while (1) {
            size_of_sockaddr_in = sizeof(struct sockaddr_in);
            fprintf(stderr, "Listening & Accepting...\n");
            if ((server_session_socket = accept(local_listen_socket, (struct sockaddr*)(&client_addr_info_struct), &size_of_sockaddr_in)) == -1) {  // 服务器阻塞, 直到接受到客户连接
                fprintf(stderr, "ERR accept():%s\n\a", strerror(errno));
                exit(1);
            }
     
            fprintf(stderr, "Got connection from %s\n", inet_ntoa(client_addr_info_struct.sin_addr)); // 网络地址 转换成 字符串
            if ((read_got_bytes_nr = read(server_session_socket, buffer, 1024)) == -1) {
                fprintf(stderr, "ERR read():%s\n", strerror(errno));
                exit(1);
            }
            buffer[read_got_bytes_nr] = '\0';
            printf("Server received %s\n", buffer); /* 这个对话服务已经结束 */
            close(server_session_socket); /* 下一个 */
        }
     
        /* 结束通讯 */
        close(local_listen_socket);
        exit(0);
    }

    #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 <arpa/inet.h> 
     
    #define portnumber 3333
     
    int main(int argc, char* argv[]) {
        int local_socket;
        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);
        }
     
        /* 使用hostname查询host 名字 */
        if ((host = gethostbyname(argv[1])) == NULL) {
            fprintf(stderr, "ERR gethostbyname\n");
            exit(1);
        }
     
        /* 客户程序开始建立 local_socket描述符 */
        if ((local_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) { // AF_INET:Internet;SOCK_STREAM:TCP
            fprintf(stderr, "ERR socket:%s\a\n", strerror(errno));
            exit(1);
        }
     
        /* 客户程序填充服务端的资料 */
        bzero(&server_addr, sizeof(server_addr)); // 初始化,置0
        server_addr.sin_family = AF_INET;          // IPV4
        server_addr.sin_port = htons(portnumber);  // (将本机器上的short数据转化为网络上的short数据)端口号
        server_addr.sin_addr = *((struct in_addr*)host->h_addr); // IP地址
     
        /* 客户程序发起连接请求 */
        if (connect(local_socket, (struct sockaddr*)(&server_addr), sizeof(struct sockaddr)) == -1) {
            fprintf(stderr, "ERR connect:%s\a\n", strerror(errno));
            exit(1);
        }
     
        /* 连接成功了 */
        printf("Please typein a string:\n");
     
        /* 读取和发送数据 */
        fgets(buffer, 1024, stdin);
        write(local_socket, buffer, strlen(buffer));
        
        /* 结束通讯 */
        close(local_socket);
        exit(0);
  • 编译
  •  
  • gcc -o server-while-tcp.out server-while-tcp.c

  • gcc -o client.out client.c

  • ./server-while-tcp.out

     

  • ./client.out 192.168.1.133

  • 结果

三,修改服务器为多线程模式

  • server源码
  • client源码
  • 编译
  • 运行
  •  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值