免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7202 | 回复: 7
打印 上一主题 下一主题

有人能给个非阻塞socket的例子吗非常感谢 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-07-03 14:51 |只看该作者 |倒序浏览
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
2 [报告]
发表于 2009-07-03 14:51 |只看该作者

回复 #1 luoleicn 的帖子

http://www.ibm.com/developerworks/cn/aix/library/au-highperform1/
看看这个,这个已经有了读和写。
如果用到windows,把关键错误字换成windows下的非阻塞那个错就行了。

尤其注意的就是,他并没有加锁。
如果多线程使用时,要加锁,因为非阻塞,往往分片了,不是一次完成。
不加锁,如果多线程同时操作,会出问题。
还有非阻塞的connect,看看unix网络编程就行了。
其他的也就用不着非阻塞了。

经常看到会像这个链接那种如果出现EAGAIN之类错时,直接continue,我还是建议给个计数器,如果重复次数过多,放弃。避免理论上存在无休止的循环。不过实际会不会这样,我也不知道,只不过我是这样做的增加计数。

[ 本帖最后由 urapple 于 2009-7-3 16:37 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2009-07-03 15:07 |只看该作者

论坛徽章:
0
4 [报告]
发表于 2009-07-03 15:08 |只看该作者

回复 #1 luoleicn 的帖子

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/fcntl.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/resource.h>

#define MAXBUF 1024

int set_noblock_socket(int sockfd)
{
    if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1) {
        return -1;
    }

    return 0;
}

int handle_message(int sockfd)
{
    int len = 1;
    char buff[MAXBUF+1] = {0};

    while (len != 0)
    {
        len = recv(sockfd, buff, MAXBUF, 0);
        if (len < 0) {
            perror("recv error");
            close(sockfd);
            return -1;
        } else if (len > 0) {
            printf("Recved:%s, and len is:%d \n", buff, len);
            len = send(sockfd, buff, len, 0);
            if (len < 0) {
                perror("send error");
                close(sockfd);
            }
            memset(buff, 0, MAXBUF);
        } else { //==0
            printf("Disconnected by peer!\n");
            close(sockfd);
            return -1;
        }
    }

    return len;
}

int main()
{
    int n, srv_sock, client_sock, ret;
    socklen_t len;
    unsigned int serv_port;
    struct sockaddr_in serv_addr, cli_addr;

    if ((srv_sock = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        return -1;
    }

    bzero(&serv_addr, sizeof(struct sockaddr_in));
    serv_addr.sin_family = PF_INET;
    serv_addr.sin_port = htons(32321);
    serv_addr.sin_addr.s_addr = INADDR_ANY;

    if (bind(srv_sock, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1) {
        perror("bind");
        close(srv_sock);
        return -1;
    }

    if (listen(srv_sock, 5) < 0){
        perror("listen");
        close(srv_sock);
        return -1;
    }

    while (1) {
        client_sock = accept(srv_sock, (struct sockaddr *)&cli_addr, &len);
        if (client_sock < 0) {
            perror("accept");
            continue;
        } else {
            printf("connect from:%s:%d\n", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port));
        }

        ret = handle_message(client_sock);
        if (ret < 0) {
            printf("handle_message error\n");
        }
        printf("handle over\n");
    }

    close(srv_sock);

    return 0;
}

论坛徽章:
0
5 [报告]
发表于 2009-07-03 15:45 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
6 [报告]
发表于 2009-07-03 15:55 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
7 [报告]
发表于 2009-07-03 16:22 |只看该作者

回复 #1 luoleicn 的帖子

上面都到5层楼了,还没有看到一个正确的例子,5楼接近正确。

论坛徽章:
0
8 [报告]
发表于 2009-07-03 16:24 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP