📄 network.c
字号:
/*
Network.c TCP/IP
by home well
*/
#include "sample.h"
#include <basic.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tstring.h>
#include <btron/errcode.h>
#include <btron/outer.h>
#include <btron/bsocket.h>
#define P printf
#define EC(er) ((er)>>16)
#define MIN_SIZE 64
#define MAX_SIZE (2 * 1024)
#define MAX_BLKSZ (MAX_SIZE / MIN_SIZE)
LOCAL UB dbuf[MAX_SIZE];
typedef struct {
UB buf[MAX_SIZE];
W cnt;
W head;
W tail;
}DATABUF;
DATABUF sendbuf;
LOCAL W remote_port = 20000;
LOCAL W local_port = 20000;
//LOCAL B remote_name[64];
LOCAL B local_name[64];
LOCAL struct sockaddr_in local_addr;
LOCAL struct sockaddr_in remote_addr;
LOCAL FUNCP Ser_fn = 0;
//LOCAL B ipstr[100];
LOCAL Bool Listen_flag;
LOCAL Bool SerConn_flag;
LOCAL Bool LocConn_flag;
LOCAL Bool Accept_flag;
WERR Task_accept_ID;
LOCAL W Local_socket;
LOCAL W Remote_socket;
LOCAL W Server_socket;
/*
ホストアドレスの艰评
*/
LOCAL WERR GetHostAddr(B* name, UW *addr)
{
W c, n, v;
UB *ip;
B *p, hbuf[HBUFLEN];
struct hostent hostent;
ip = (UB*)addr;
for (p = name, n = v = 0; (c = *p++) != 0; ) {
if (c >= '0' && c <= '9') {
if ((v = v * 10 + (c - '0')) > 255)
break;
}
else if (c == '.' && n < 3){
ip[n++] = v;
v = 0;
}
else
break;
}
if (c == 0 && n == 3) {
ip[3] = v;
return ER_OK;
}
if ((n = so_gethostbyname(name, &hostent, hbuf)) < ER_OK)
return n;
memcpy(addr, hostent.h_addr_list[0], sizeof(UW));
return 1;
}
////////////////////// client recv data /////////////////////////////////////////
LOCAL VOID Local_Task(W arg)
{
W n;
WERR Wer;
LocConn_flag = 1;
P("taskdata:creat\n");
while(LocConn_flag){
slp_tsk(50);
Wer = so_recv(Local_socket, (B*)dbuf, 100, 0);
if(Wer>0){
if(Ser_fn)
Ser_fn(dbuf,Wer);
}
else if(Wer==EX_WOULDBLOCK)
continue;
else
LocConn_flag = 0;
}
P("C:offline\n");
if(Ser_fn)
Ser_fn("C:Offline!",10);
so_close(Local_socket);
Local_socket = -1;
ext_tsk();
}
/////////////////////// accepting net ///////////////////////////////////////////////////////
LOCAL VOID DoServer(W arg)
{
W er, n;
WERR Wer;
struct sockaddr_in from;
SerConn_flag = 0;
Listen_flag = 1;
P("S:accepting!\n");
while (Listen_flag)
{
slp_tsk(50);
if(LocConn_flag)
continue;
n = sizeof(from);
Remote_socket = so_accept(server_socket, (SOCKADDR *)&from , &n);
if(Remote_socket==EX_WOULDBLOCK)
continue;
else if (Remote_socket < ER_OK) {
Listen_flag = 0;
continue;
}
SerConn_flag = 1;
P("S:accept ok\n");
if(Ser_fn)
Ser_fn("ACK OK!",8);
/////////////////derver recv data ////////////////
while(SerConn_flag){
slp_tsk(50);
Wer = so_recv(Remote_socket, (B*)dbuf, 100, 0);
if(Wer>0){
if(Ser_fn)
Ser_fn(dbuf,Wer);
}
else if(Wer==EX_WOULDBLOCK)
continue;
else
SerConn_flag = 0;
}
P("S:offline\n");
if(Ser_fn)
Ser_fn("S:Offline!",10);
so_close(Remote_socket);
}
ext_tsk();
}
/*
EXPORT 对外接口
*/
EXPORT W setSer_fn(FUNCP f)
{
if(f)
Ser_fn = f;
}
EXPORT W delSer_fn(void)
{
Ser_fn = 0;
}
EXPORT W Listen_net(void)
{
WERR err;
W er;
unsigned long *addr;
B addrbuf[64];
so_gethostname(local_name, sizeof(local_name));
memset((B*)&local_addr, 0, sizeof(local_addr));
if (GetHostAddr(local_name, (UW*)&local_addr.sin_addr.s_addr) < ER_OK) {
P("unknown Host:%s\n", local_name);
return 0;
}
local_addr.sin_family = AF_INET;
local_addr.sin_port = htons(local_port);
addr = &local_addr.sin_addr.s_addr;
sprintf(addrbuf,"%d.%d.%d.%d",(UB)(*addr),(UB)(*addr>>8),(UB)(*addr>>16),*addr>>24);
P("\nHost:%s--%s\n", local_name,addrbuf);
Server_socket = so_socket(PF_INET, SOCK_STREAM, 0);
if (Local_socket < ER_OK) {
P("S:socket err\n");
goto EXIT;
}
er = so_bind(Server_socket, (SOCKADDR *)&local_addr, sizeof(local_addr));
if (er < ER_OK) {
P("S:bind err\n");
goto EXIT;
}
er = so_listen(Server_socket, 5);
if (er < ER_OK) {
P("S:listen err\n");
goto EXIT;
}
// no block
err = so_fcntl(Server_socket,F_GETFL,0);
so_fcntl(Server_socket,F_SETFL,err|O_NDELAY);
Listen_flag = 1;
if ((err = cre_tsk(DoServer, -1, 0)) < 0) {
printf("ACCEPT tsk create error = %d\n", err);
goto EXIT;
}
Task_accept_ID = err;
printf("start_net\n");/**/
return 0;
EXIT:
if (Server_socket >= 0){
so_close(Server_socket);
Server_socket = -1;
Listen_flag = 0;
}
return -1;
}
EXPORT W StopListen_net(void)
{
if (Server_socket >= 0){
so_close(Server_socket);
Server_socket = -1;
slp_tsk(300);
}
printf("stop_net\n");
return 0;
}
//////////////////////// start network ///////////////////////////////////////////////
EXPORT W Start_net(void)
{
Listen_net();
}
EXPORT W Stop_net(void)
{
StopListen_net();
}
// dial
// remote_name --- remote ip
EXPORT W Dial(B *remote_name)
{
W er,connect_cnt;
unsigned long *addr1,*addr2,*addr;
B addrbuf[64];
if(SerConn_flag||LocConn_flag)
return -1;
so_gethostname(local_name, sizeof(local_name));
memset((B*)&local_addr, 0, sizeof(local_addr));
if (GetHostAddr(local_name, (UW*)&local_addr.sin_addr.s_addr) < ER_OK) {
P("unknown Host:%s\n", local_name);
return 0;
}
local_addr.sin_family = AF_INET;
local_addr.sin_port = htons(local_port);
addr = &local_addr.sin_addr.s_addr;
sprintf(addrbuf,"%d.%d.%d.%d",(UB)(*addr),(UB)(*addr>>8),(UB)(*addr>>16),*addr>>24);
P("\nHost:%s--%s Dial\n", local_name,addrbuf);
Local_socket = so_socket(PF_INET, SOCK_STREAM, 0);
if (Local_socket < ER_OK) {
P("S:socket err\n");
goto EXIT;
}
memset((B*)&remote_addr, 0, sizeof(remote_addr));
if (GetHostAddr(remote_name, (UW*)&remote_addr.sin_addr.s_addr) < ER_OK) {
P("unknown host: %s\n", local_name);
goto EXIT;
}
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(remote_port);
addr1 = &local_addr.sin_addr.s_addr;
addr2 = &remote_addr.sin_addr.s_addr;
er = so_fcntl(Local_socket,F_GETFL,0);
so_fcntl(Local_socket,F_SETFL,er|O_NDELAY);
printf("Dial:%d.%d.%d.%d\n",(UB)(*addr2),(UB)(*addr2>>8),(UB)(*addr2>>16),*addr2>>24);
P("C:connecting!\n");
connect_cnt = 0;
er = so_connect(Local_socket, (SOCKADDR *)&remote_addr, sizeof(remote_addr));
if(er<0){
P("C: connect err\n");
goto EXIT;
}
P("C:Dial OK\n");
if(Ser_fn)
Ser_fn("Dial OK!",8);
if ((er = cre_tsk(Local_Task, -1, (W)&Local_socket)) < 0) {
printf("Local_Task create error = %d\n", er);
goto EXIT;
}
return 0;
EXIT:
so_close(Local_socket);
Local_socket = -1;
return -1;
}
EXPORT W Hangup(void)
{
SerConn_flag = 0;
LocConn_flag = 0;
slp_tsk(100);
if(Local_socket){
so_close(Local_socket);
Local_socket = -1;
}
return 0;
}
EXPORT W Writedatabuf(B *databuf,W len)
{
W Tmp_socket;
if(SerConn_flag)
Tmp_socket = Remote_socket;
else if(LocConn_flag)
Tmp_socket = Local_socket;
else
return 0;
return so_send(Tmp_socket,databuf,len,0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -