您的位置:首页 > 编程语言

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

2016-10-19 21:04 423 查看
socket(PF_INET,SOCK_STREAM,0)
或socket(AF_INET,SOCK_STREAM,0)

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

1、参数domain指明通信域,如PF_UNIX(unix域),PF_INET(IPv4),PF_INET6(IPv6)等2、type指明通信类型,最常用的如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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐