国嵌实时监控系统代码笔记(二)net.c

socket(PF_INET,SOCK_STREAM,0) socket(AF_INET,SOCK_STREAM,0)

 socket()系统调用,带有三个参数: 

1、参数domain指明通信域,如PF_UNIX(unix)PF_INET(IPv4)PF_INET6(IPv6)2type指明通信类型,最常用的如SOCK_STREAM(面向连接可靠方式,  比如TCP)SOCK_DGRAM(非面向连接的非可靠方式,比如UDP)等。  SOCK_STREAM 是数据流,一般是tcp/ip协议的编程,SOCK_DGRAM分是数据抱,udp协议网络编程。

3、参数protocol指定需要使用的协议。虽然可以对同一个协议  家族(protocolfamily)(或者说通信域(domain))指定不同的协议  参数,但是通常只有一个。对于TCP参数可指定为IPPROTO_TCP,对于  UDP可以用IPPROTO_UDP。你不必显式制定这个参数,使用0则根据前两个参数使用默认的协议。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sys/epoll.h>

#include <main.h>

//							c即是tcp_cli 			s即是tcp_srv

void net_send(struct tcp_cli * tc, void *buf, int len)
{
	struct tcp_cli *c = (struct tcp_cli*)tc;
	struct tcp_srv *s = c->srv;
     
    epoll_del_event(s->epfd, c->ev_rx);//停止接收,避免干扰
    c->buf = buf;//c即是tcp_cli
    c->len = len;
    epoll_add_event(s->epfd, c->ev_tx);//开启发送
}

static void rx_app_handler(int sock, void *arg)
{
	struct tcp_cli *c = arg;	//arg从c即client那儿来,因为在创建事件时把client作为arg参数保存进去了
	int res = 0;   

    	unsigned char            *pbuf;//数据保存到pbuf
    
    	pbuf  = &c->req[0]; 

        res = read(c->sock, pbuf, FRAME_HDR_SZ);
        process_incoming(c);
}

static void tx_app_handler(int sock, void *arg)
{
    struct tcp_cli *c = arg;
    struct tcp_srv *s = c->srv;
    int res = 0;

    res = send(sock, c->buf, c->len, 0);//发送数据

    if (res > 0) {
        c->len -= res;
        if (c->len == 0) {
            epoll_del_event(s->epfd, c->ev_tx);//停止发送
            epoll_add_event(s->epfd, c->ev_rx);//开启接收
        }
    } 
}


int build_ack(unsigned char *rsp, unsigned char type, unsigned char id, 
                         unsigned char len, unsigned char *data)
{
    rsp[LEN_POS]  = len;
    rsp[CMD0_POS] = type;
    rsp[CMD1_POS] = id;
    memcpy(&rsp[DAT_POS], data, len);
	//由data所指内存区域复制len个字节到&rsp[DAT_POS]所指内存区域。		
    return len + FRAME_HDR_SZ;
}

int net_sys_init( )
{
	 struct sockaddr_in addr;
	 struct sockaddr_in sin;
	 struct tcp_cli *c;
         int new_sock;
	 int len;
	
        struct tcp_srv *s = calloc(1, sizeof(struct tcp_srv));

        s->epfd = srv_main->epfd;
	
	 s->sock = socket(AF_INET, SOCK_STREAM,     0);
									//通信域  tcp/ip协议的编程	协议
									//ipv4		数据流						0为默认
	addr.sin_addr.s_addr = INADDR_ANY;
												//可以使用任何ip地址通信
	addr.sin_family = AF_INET;//ipv4协议
	
  addr.sin_port = htons (DEF_TCP_SRV_PORT);//自定义端口 #define DEF_TCP_SRV_PORT        19868
	
	bind(s->sock, (struct sockaddr*)&addr, sizeof(struct sockaddr));//将sock和地址绑定起来
		
	listen(s->sock, 5);	//连接数是5

       new_sock = accept(s->sock, (struct sockaddr*)&sin, &len);//等待客户端连接
		//保存客户端的fd		 					连接上来的客户端的地址	
      c = calloc(1, sizeof(struct tcp_cli));
 
      c->sock = new_sock; //保存客户端的fd
      memcpy(&c->addr, &sin, len);//将客户端的ip地址拷贝到sin中
      c->srv = s;
//      c->req_total = FRAME_HDR_SZ;
       
      c->ev_rx = epoll_event_create(c->sock,EPOLLIN,rx_app_handler, c);//把client即是c作为arg参数保存进去																					
      c->ev_tx = epoll_event_create(c->sock,EPOLLOUT,tx_app_handler, c);

      

       epoll_add_event(c->srv->epfd, c->ev_rx);

	//return s;
       
       srv_main->srv = s;
       
       return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值