网络编程\作业\2024\8\21

1. 

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/select.h>
int main(int argc, const char *argv[])
{
    //创建套接字
    int sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd<0)
    {
        perror("socket create error");
        return -1;
    }
    printf("sockfd create success\n");

    int opt=1;
    setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

    //绑定套接字
    struct sockaddr_in saddr,caddr;
    saddr.sin_family=AF_INET;
    saddr.sin_port=htons(atoi(argv[1]));
    saddr.sin_addr.s_addr=inet_addr(argv[2]);
    int len=sizeof(caddr);

    if(bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr))<0)
    {
        perror("bind error");
        return -1;
    }
    printf("bind success\n");

    //创建监听队列
    if(listen(sockfd,5)<0)
    {
        perror("liseten is error");
        return -1;
    }

    //创建一个存储文件描述符的表
    fd_set readfds,tempfds;
    //对表初始化清空
    FD_ZERO(&readfds);
    //将需要的文件描述符添加到表内
    FD_SET(sockfd,&readfds);
    FD_SET(0,&readfds);

    int maxfd=sockfd;

    char send_buf[128];
    char recv_buf[128];
    while(1)
    {
        bzero(send_buf,sizeof(send_buf));
        bzero(recv_buf,sizeof(recv_buf));
        //将原表内的内容拷贝到备份表
        tempfds=readfds;
        //利用select 进行轮训监测
        if( select(maxfd+1,&tempfds,NULL,NULL,NULL) < 0 )
        {
            perror("select is err:");
            return -1;
        }


        //判断文件描述符是否产生响应
        if(FD_ISSET(0,&tempfds))
        {
            printf("please enter:");
            fgets(send_buf,sizeof(send_buf),stdin);
            if( send_buf[strlen(send_buf)-1] == '\n' )
                send_buf[strlen(send_buf)-1] = '\0';

            for(int i=4;i<=maxfd;i++)
            {
                if(FD_ISSET(i,&readfds))
                {
                    send(i,send_buf,sizeof(send_buf),0);//发送信息
                }
            }
            printf("发送成功\n");
        }


        //判断文件描述符是否产生响应 
        if(FD_ISSET(sockfd,&tempfds))
        {
            int acceptfd=accept(sockfd ,(struct sockaddr*)&caddr,&len);
            if(acceptfd<0)
            {
                perror("accept error");
                return -1;
            }
            FD_SET(acceptfd,&readfds);
            if(acceptfd>maxfd)
            {
                maxfd=acceptfd;
            }
            printf("new client connected: %d\n", acceptfd);

            for(int i=4;i<=maxfd;i++)
            {
                if(FD_ISSET(i,&tempfds))
                {
                    int ret=recv(i,recv_buf,sizeof(recv_buf),0);
                    if(ret<0)
                    {                                                                                                             
                        perror("recv error");
                        return -1;
                    }
                    else if(ret==0)
                    {
                        close(i);//关闭i文件描述符
                        FD_CLR(i,&readfds);
                        if(i == maxfd)
                        {
                            maxfd--;
                        }
                        printf("client exit\n");
                    }
                    else
                    {
                        printf("client:%d %s\n",i,recv_buf);
                    }

                }
            }
        }
    }

    close(sockfd);
    return 0;
}

2.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>

int main(int argc, const char *argv[])
{
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <port> <ip>\n", argv[0]);
        return -1;
    }

    // 创建套接字
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket create error");
        return -1;
    }
    printf("socket create success\n");

    struct sockaddr_in caddr;
    caddr.sin_family = AF_INET;
    caddr.sin_port = htons(atoi(argv[1]));
    caddr.sin_addr.s_addr = inet_addr(argv[2]);

    // 链接服务器
    if (connect(sockfd, (struct sockaddr*)&caddr, sizeof(caddr)) < 0) {
        perror("connect error");
        close(sockfd);
        return -1;
    }

    // 定义发送信息的容器
    char send_buf[128] = {0};
    char recv_buf[128] = {0};

    fd_set readfds, tempfds;
    int maxfd = sockfd;

    while (1) {
        // 每次循环开始时重新初始化 readfds
        FD_ZERO(&readfds);
        FD_SET(0, &readfds);
        FD_SET(sockfd, &readfds);

        tempfds = readfds;
        if (select(maxfd + 1, &tempfds, NULL, NULL, NULL) < 0) {
            perror("select error");
            close(sockfd);
            return -1;
        }

        // 处理标准输入
        if (FD_ISSET(0, &tempfds)) {
            bzero(send_buf, sizeof(send_buf));
            printf("请输入: ");
            if (fgets(send_buf, sizeof(send_buf), stdin) != NULL) {
                size_t len = strlen(send_buf);
                if (len > 0 && send_buf[len - 1] == '\n') {
                    send_buf[len - 1] = '\0';  // 去掉换行符
                }

                // 发送
                if (send(sockfd, send_buf, strlen(send_buf), 0) < 0) {
                    perror("send error");
                    close(sockfd);
                    return -1;
                }
            }
        }

        // 处理从服务器接收的数据
        if (FD_ISSET(sockfd, &tempfds)) {
            bzero(recv_buf, sizeof(recv_buf));
            int ret = recv(sockfd, recv_buf, sizeof(recv_buf) - 1, 0);  // 留出空间给'\0'
            if (ret < 0) {
                perror("recv error");
                close(sockfd);
                return -1;
            } else if (ret == 0) {
                printf("Server disconnected\n");
                close(sockfd);
                return 0;
            } else {
                recv_buf[ret] = '\0';  // 确保接收到的数据是以'\0'结尾
                printf("recv: %s\n", recv_buf);
            }
        }
    }

    close(sockfd);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值