linux下用select写socket demo

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <map>
#include <string>
#include <string.h>
const int port = 8080;
int main()
{
    int sock_ser = socket(AF_INET, SOCK_STREAM, 0);
    if(sock_ser < 0)
    {
	perror("socket()");
	return -1;
    }
    sockaddr_in addr_ser;
    addr_ser.sin_family = AF_INET;
    addr_ser.sin_port = htons(port);
    addr_ser.sin_addr.s_addr = INADDR_ANY;
    if(bind(sock_ser, (struct sockaddr *)&addr_ser, sizeof(addr_ser))<0)
    {
	perror("bind()");
	return -2;
    }
    if(listen(sock_ser, 5)<0)
    {
	perror("listen");
	return -3;
    }
    printf("listening...\n");

    std::map<int, std::string> cltlist;  //保存服务端和客户端的连接和地址
    std::map<int, std::string>::iterator it;
    fd_set reads, temps;
    int maxfd = sock_ser;
    struct sockaddr_in cltaddr;
    char buf[1024];

    FD_ZERO(&reads);
    FD_SET(sock_ser, &reads);
    cltlist[sock_ser] = "server";

    while(1)
    {
	struct timeval wait_time = {5,0};
	temps = reads;
	int fd_count = select(maxfd+1, &temps, NULL, NULL, &wait_time);
	if(fd_count < 0)
	{
	    perror("select()");
	    return -4;
	}
	if(fd_count==0)
	{
	    printf("timeout\n");
	    continue;
	}
	for(it = cltlist.begin();it!=cltlist.end();it++)
	{
	    if(!FD_ISSET(it->first, &temps))
		continue;
	    memset(buf, 0, sizeof(buf));
	    if(it->first == sock_ser)	    //检测到新连接
	    {
		socklen_t addr_len = sizeof(cltaddr);
		int cltfd = accept(sock_ser, (struct sockaddr *)&cltaddr, &addr_len);
		if(cltfd < 0)
		{
		    perror("accept()");
		    return -5;
		}
		sprintf(buf, "%s:%d",
			inet_ntop(AF_INET, &cltaddr.sin_addr, buf, sizeof(buf)),
			ntohs(cltaddr.sin_port));
		printf("connected by %s\n", buf);
		cltlist[cltfd] = buf;
		if(maxfd<cltfd)
		    maxfd = cltfd;
		FD_SET(cltfd, &reads);
	    }
	    else    //读客户端发过来的信息
	    {
		ssize_t read_s = read(it->first, buf, sizeof(buf));
		if(read_s < 0)
		{
		    perror("read()");
		    return -6
		}
		else if(read_s == 0)
		{
		    printf("%s leave..\n", it->second.c_str());
		    FD_CLR(it->first, &reads);
		    //这里还要删除map中的元素,不过不能在遍历中删,先不做了,
		    continue;
		}
		printf("%s say: %s", it->second.c_str(), buf);
	    }
	}
    }
    close(sock_ser);
    return 0; 
} 

转载于:https://www.cnblogs.com/onestow/p/8214385.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值