c语言网络编程-标准步骤(改进版)

 更新时间:2014年01月30日 22:14:10   作者:  
这篇文章主要介绍了c语言网络编程-标准步骤的改进说明,需要的朋友可以参考下

server.c

复制代码 代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <sys/errno.h>

#define PORT 4444
#define BACKLOG 5
#define MAX_FD 256

void setnonblocking(int);

int main(int argc, char *argv[]) {
    int sock_fd, new_fd, new_fd2, epfd, nfds;
    struct sockaddr_in server_addr, client_addr;
    int sin_size;
    int nbytes;
    int on = 1;
    char buffer[1024];
    struct epoll_event ev, events[20];

    epfd = epoll_create(MAX_FD);

    if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
    setnonblocking(sock_fd);

    ev.data.fd  = sock_fd;
    ev.events   = EPOLLIN | EPOLLET;
    epoll_ctl(epfd, EPOLL_CTL_ADD, sock_fd, &ev);

    memset(&server_addr, 0, sizeof(struct sockaddr_in));
    server_addr.sin_family      = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port        = htons(PORT);

    if (bind(sock_fd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)) == -1) {
        perror("bind");
        exit(1);
    }

    if (listen(sock_fd, BACKLOG) == -1) {
        perror("listen");
        exit(1);
    }

    printf("Server start... \n");

    sin_size = sizeof(struct sockaddr_in);

    int i;

    while (1) {
        nfds = epoll_wait(epfd, events, 20, 500);
        for (i = 0; i < nfds; i++) {
            if (events[i].data.fd == sock_fd) {
                if ((new_fd = accept(sock_fd, (struct sockaddr *)(&client_addr), &sin_size)) == -1) {
                    perror("accept");
                    exit(1);
                }
                printf("Server get connection from %s\n", inet_ntoa(client_addr.sin_addr));
                setnonblocking(new_fd);
                ev.data.fd = new_fd;
                ev.events = EPOLLIN | EPOLLET;
                epoll_ctl(epfd, EPOLL_CTL_ADD, new_fd, &ev);

            } else if (events[i].events & EPOLLIN) {
                if ((new_fd2 = events[i].data.fd) < 0) continue;
                if ((nbytes = read(new_fd2, buffer, 1024)) == -1) {
                    perror("read");
                    exit(1);
                } else if (nbytes == 0) {
                    close(new_fd2);
                    events[i].data.fd = -1;
                }
                printf("Server read from %s\n", inet_ntoa(client_addr.sin_addr));
                ev.data.fd = new_fd2;
                ev.events = EPOLLOUT | EPOLLET;
                epoll_ctl(epfd, EPOLL_CTL_MOD, new_fd2, &ev);

            } else if (events[i].events & EPOLLOUT) {
                new_fd2 = events[i].data.fd;
                write(new_fd2, "Server Received", 16);
                ev.data.fd = new_fd2;
                ev.events = EPOLLIN | EPOLLET;
                epoll_ctl(epfd, EPOLL_CTL_MOD, new_fd2, &ev);
            }
        }
    }

    return 0;
}

void setnonblocking(int fd) {
    int opts;
    if ((opts = fcntl(fd, F_GETFL)) < 0) {
        perror("fcntl(fd, F_GETFL");
        exit(1);
    }

    opts = opts | O_NONBLOCK;
    if (fcntl(fd, F_SETFL, opts) < 0) {
        perror("fcntl(fd, F_SETFL, opts");
        exit(1);
    }
}

client.c

复制代码 代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define PORT 4444

int main(int argc, char *argv[]) {
    int sock_fd;
    struct sockaddr_in server_addr;
    struct hostent *host;
    char buffer[1024];

    if (argc < 2) {
        perror("Need hostname");
        exit(1);
    }

    if ((host = gethostbyname(argv[1])) == NULL) {
        perror("gethostbyname");
        exit(1);
    }

    if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    memset(&server_addr, 0, sizeof(struct sockaddr_in));
    server_addr.sin_family  = AF_INET;
    server_addr.sin_port    = htons(PORT);
    server_addr.sin_addr    = *((struct in_addr *)host->h_addr);

    if (connect(sock_fd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)) == -1) {
        perror("connect");
        exit(1);
    }

    while (1) {
        printf("Please input something:\n");
        fgets(buffer, 1024, stdin);
        write(sock_fd, buffer, strlen(buffer));
        read(sock_fd, buffer, 1024);
        printf("From server: %s\n", buffer);
    }
    close(sock_fd);

    return 0;
}

相关文章

  • 在Vitis IDE中如何使用第三方库 libtiff 保存 tiff 文件

    在Vitis IDE中如何使用第三方库 libtiff 保存 tiff 文件

    这篇文章主要介绍了在Vitis IDE中如何使用第三方库 libtiff 保存 tiff 文件,本文通过图文实例相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • websocket++简单使用及实例分析

    websocket++简单使用及实例分析

    下面小编就为大家带来一篇websocket++简单使用及实例分析。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-05-05
  • C++之Qt5双缓冲机制案例教程

    C++之Qt5双缓冲机制案例教程

    这篇文章主要介绍了C++之Qt5双缓冲机制案例教程,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C++ OpenMP简单介绍

    C++ OpenMP简单介绍

    这篇文章主要介绍了C++ OpenMP简介,OpenMP 还支持自定义数据类型的归约操作,需要通过omp declare reduction指令来声明自定义操作符和数据类型的归约方式,感兴趣的朋友一起看看吧
    2023-05-05
  • C++中套接字库sockpp的使用详解

    C++中套接字库sockpp的使用详解

    sockpp是一个开源、简单、现代的C++套接字库,这篇文章主要为大家详细介绍一下套接字库sockpp的使用,文中的示例代码讲解详细,感兴趣的小伙伴可以学习一下
    2023-11-11
  • 关于C++中引用和指针的区别详解

    关于C++中引用和指针的区别详解

    这篇文章主要介绍了关于C++中引用和指针的区别详解,
    2023-07-07
  • Qt界面美化之自定义qss样式表的详细步骤

    Qt界面美化之自定义qss样式表的详细步骤

    很多人应该和我一样,想做界面才接触的Qt,结果就是做不出来华丽的界面,下面这篇文章主要给大家介绍了关于Qt界面美化之自定义qss样式表的详细步骤,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-03-03
  • C语言栈之顺序栈

    C语言栈之顺序栈

    这篇文章主要为大家详细介绍了C语言的顺序栈,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • C++编写的WebSocket服务端客户端实现示例代码

    C++编写的WebSocket服务端客户端实现示例代码

    本文主要介绍了C++编写的WebSocket服务端客户端实现示例代码,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • 在C++中实现高效的数组原地轮转的方法总结

    在C++中实现高效的数组原地轮转的方法总结

    在 C++ 中,可以通过多种方式实现数组的轮转操作,以下是几种常见的实现方法及其对应的代码示例,文中通过代码示例介绍的非常详细,具有一定的参考价值,需要的朋友可以参考下
    2025-04-04

最新评论