📄 commsdms.c
字号:
int(*accept_fn)(struct TCP_Stream_Node_t *srv_node,char *new_node_name))
{
struct hostent* h;
struct servent* s;
struct sockaddr_in sin;
int sk;
char temp_buffer[512];
struct TCP_Stream_Node_t *node;
unsigned short port; // Added by Jason, 97.10.5
char RealIPMode = 0; // Added by Jason, 97.10.5
if (strchr(hname, '.')) RealIPMode = 1; // Added by Jason, 97.10.5
/* 1. get host and services information */
if (!RealIPMode) { // Added by Jason, 97.10.5
h = gethostbyname(hname);
if (!h) {
sprintf(temp_buffer,"CAPI:gethostbyname: failed to get host information for %s",hname);
(*record_err)(temp_buffer);
return -1;
}
s = getservbyname(sname,"tcp");
if (!s) {
sprintf(temp_buffer,"CAPI:getservbyname: failed to get services information for %s",sname);
(*record_err)(temp_buffer);
return -1;
}
}
bzero(&sin, sizeof(sin));
sin.sin_family = AF_INET;
if (!RealIPMode) { // Added by Jason, 97.10.5
sin.sin_port = (unsigned int)s->s_port;
bcopy(h->h_addr, &sin.sin_addr, sizeof(sin.sin_addr));
}
else { // Added by Jason, 97.10.5
sscanf(sname, "%d", &port);
sin.sin_port = (unsigned int)htons(port);
sin.sin_addr.s_addr = inet_addr(hname);
}
/* 2. get a idle TCP stream node */
node = GetIdleTcpNode();
if (node == NULL) {
(*record_err)("CAPI:GetIdleTcpNode: can not get a idle node !");
return -1;
}
/* 3. create a socket for the node */
sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sk < 0) {
(*record_err)("CAPI:socket: can not open socket for node !");
return -1;
}
/* 4. setup information for the node */
node->type = type;
node->status = TCP_WAIT_CONNECT;
strcpy(node->name,name);
strcpy(node->sname,sname);
strcpy(node->hname,hname);
node->socket = sk;
bcopy(&sin,node->sin,sizeof(struct sockaddr_in));
/* === Add stx & etx by Jason, 97.8.19 === */
if (strcmp(stx, "\x02")==0 && strcmp(etx, "\x03")==0)
node->format = 1;
else
node->format = 0;
strcpy(node->stx, stx);
strcpy(node->etx, etx);
/* =======================================*/
switch (node->type)
{
case TCP_SERVER:
setsockopt(node->socket,SOL_SOCKET,SO_REUSEADDR,(char *)0,0);
if (bind(node->socket,(struct sockaddr*)node->sin, sizeof(struct sockaddr_in)) < 0) {
node->status = TCP_WAIT_RETRY;
perror("bind:"); /* For debug */
close(node->socket);
node->socket = -1;
sprintf(temp_buffer,"CAPI:can not bind listen socket for %s",node->name);
(*record_err)(temp_buffer);
return -1;
}
if (listen(node->socket,5) < 0) {
node->status = TCP_WAIT_RETRY;
perror("listen:"); /* For debug */
close(node->socket);
node->socket = -1;
sprintf(temp_buffer,"CAPI:can not start to listen for %s",node->name);
(*record_err)(temp_buffer);
return -1;
}
if (accept_fn != NULL)
node->accept_fn = accept_fn;
else
node->accept_fn = accept_connect;
break;
case TCP_CLIENT:
//if (connect(node->socket,(struct sockaddr*)node->sin, sizeof(struct sockaddr_in)) < 0) {
//Modified by Jason, 98.9.21
if (NoDelayConnect(node->socket,(struct sockaddr*)node->sin, sizeof(struct sockaddr_in)) < 0) {
node->status = TCP_WAIT_RETRY;
close(node->socket);
node->socket = -1;
sprintf(temp_buffer,"CAPI:can not connect to remote host(%s) for %s",node->hname,node->name);
(*record_err)(temp_buffer);
return 1; /* WARNING: failed to connect, but return "TRUE" to caller */
}
node->accept_fn = NULL;
node->status = TCP_CONNECTED;
break;
default:
break;
}
return 1;
}
void tcp_timer(void)
{
static int first = 1;
static time_t ot;
if (first) {
first = 0;
ot = time((time_t*)0);
return;
}
if (time((time_t*)0) >= ot+1) {
ot = time((time_t*)0);
++tick_count;
if ((tick_count%retry_time) == 0) tcp_do_retry();
}
}
void tcp_do_retry(void)
{
struct TCP_Stream_Node_t *current_node;
int sk;
char temp_buffer[512];
current_node = &fst_node;
while(current_node)
{
if (current_node->status != TCP_WAIT_RETRY) {
current_node = current_node->next;
continue;
}
switch (current_node->type)
{
case TCP_SERVER:
sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sk < 0) {
(*record_err)("CAPI:tcp_do_retry:SERVER:failed to open socket");
break;
}
current_node->socket = sk;
setsockopt(current_node->socket,SOL_SOCKET,SO_REUSEADDR,(char *)0,0);
if (bind(current_node->socket,(struct sockaddr*)current_node->sin, sizeof(struct sockaddr_in)) < 0) {
current_node->status = TCP_WAIT_RETRY;
close(current_node->socket);
current_node->socket = -1;
sprintf(temp_buffer,"CAPI:can not bind listen socket for %s",current_node->name);
(*record_err)(temp_buffer);
break;
}
if (listen(current_node->socket,5) < 0) {
current_node->status = TCP_WAIT_RETRY;
close(current_node->socket);
current_node->socket = -1;
sprintf(temp_buffer,"CAPI:can not start to listen for %s",current_node->name);
(*record_err)(temp_buffer);
}
else
current_node->status = TCP_WAIT_CONNECT;
break;
case TCP_CLIENT:
sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sk < 0) {
(*record_err)("CAPI:tcp_do_retry:CLIENT:failed to open socket");
break;
}
current_node->socket = sk;
//if (connect(current_node->socket,(struct sockaddr*)current_node->sin, sizeof(struct sockaddr_in)) < 0) {
//Modified by Jason, 98.9.21
if (NoDelayConnect(current_node->socket,(struct sockaddr*)current_node->sin, sizeof(struct sockaddr_in)) < 0) {
current_node->status = TCP_WAIT_RETRY;
close(current_node->socket);
current_node->socket = -1;
sprintf(temp_buffer,"CAPI:can not connect to remote host(%s) for %s",
current_node->hname,current_node->name);
(*record_err)(temp_buffer);
}
else
current_node->status = TCP_CONNECTED;
break;
case TCP_CHILD:
break;
case TCP_NOTUSED:
break;
default:
break;
}/* end switch */
current_node = current_node->next;
}/* end while */
}
/* === Add by Jason, 97.8.19 ==== */
/*==========================================
Procedure : SeekSTX
Function : compare stx
Para : node - tcp stream node
int ptr - pointer in buffer
Return : if not found, return 0
if found, return 1
==========================================*/
int SeekSTX(struct TCP_Stream_Node_t *node, int ptr)
{
int i;
for (i=0;i<strlen(node->stx);i++)
if (node->buffer[(ptr+i) % MAX_TCP_STREAM_BUFFER] != node->stx[i]) return 0;
return 1;
}
/*=========================================
Procedure : SeekETX
Function : compare etx
Para : node - tcp stream node
int ptr - pointer in buffer
Return : if not found, return 0
if found, return 1
==========================================*/
int SeekETX(struct TCP_Stream_Node_t *node, int ptr)
{
int i, len;
len = strlen(node->etx);
if (len == 0) /* Add by Jason, 97.12.27, Seek for No STX & ETX */
if ((ptr+1) % MAX_TCP_STREAM_BUFFER == node->tail)
return 1;
else
return 0;
for (i=0;i<len;i++)
if (node->buffer[(ptr-i+MAX_TCP_STREAM_BUFFER) % MAX_TCP_STREAM_BUFFER] != node->etx[len-i-1]) return 0;
return 1;
}
/* =======================================*/
/*
on error return -1, else return 1
*/
int CAPIProcessStream(struct TCP_Stream_Node_t *node)
{
char *read_buffer;
char *msg_buf;
int nread;
int i;
int head1,head2;
int nbytes_in_buffer;
int found_STX;
int t1;
int rc;
char end_marker;
char temp_buffer[512];
struct CAPI_Q_NODE_t q_node;
/* 1. allocate memory for reading message */
read_buffer = (char *)calloc(TCP_MAX_READ,sizeof(char));
if (read_buffer == NULL) {
(*record_err)("CAPIProcessStream: out of memory !!!");
return -1;
}
msg_buf = (char*)calloc(max_packet_size,sizeof(char));
if (msg_buf == NULL) {
free(read_buffer);
(*record_err)("CAPIProcessStream: out of memory !!!");
return -1;
}
/* 2. set message end marker */
end_marker = TCP_ETX;
/* 3. read in message flow, and ready to process message */
rc = 1;
//nread = read(node->socket,read_buffer,TCP_MAX_READ);
nread = read(node->socket,read_buffer,100);
if (nread > 0) {
/* 4. put characters into buffer */
for (i=0; i<nread; i++) {
node->buffer[node->tail] = read_buffer[i];
++node->tail;
node->tail %= MAX_TCP_STREAM_BUFFER;
/*printf("%X ",read_buffer[i]);*/ /* For debug */
}
/*printf("\n");*/ /* For debug */
/* 5. try to get packet(s) in buffer */
if (node->head < node->tail)
nbytes_in_buffer = node->tail - node->head;
else
nbytes_in_buffer = MAX_TCP_STREAM_BUFFER - node->head + node->tail;
head1 = node->head;
found_STX = 0;
for (i=0; i<nbytes_in_buffer; i++) {
/* === Modify by Jason, 97.8.19 === */
/* if(node->buffer[head1] == TCP_STX) */
if (strlen(node->stx)==0) /* No STX */
found_STX = 1;
else
if (SeekSTX(node, head1)) {
node->head = head1;
found_STX = 1;
}
/* ================================= */
/* === Modify by Jason, 97.8.19 === */
/* if(node->buffer[head1] == end_marker) */
if (SeekETX(node, head1))
/* ================================ */
{
if (found_STX)
{
found_STX = 0;
if (node->head <= head1)
{
t1 = head1 - node->head + 1;
head2 = node->head;
memcpy(msg_buf,node->buffer+head2,t1);
}
else
{
t1 = MAX_TCP_STREAM_BUFFER - node->head;
head2 = node->head;
memcpy(msg_buf,node->buffer+head2,t1);
memcpy(msg_buf+t1,node->buffer,head1+1);
t1 += head1+1;
}
/* 6. a packet received, process it, and then put the
packet into CAPI queue
*/
/* === Modify by Jason, 97.8.19 === */
/* q_node.length = t1-2; */ /* excluded STX and ETX */
if (node->format == 1) /* default stx & etx */
q_node.length = t1 - 2;
else
q_node.length = t1;
/* ================================ */
strcpy(q_node.stream_name,node->name);
q_node.content = (char *)calloc(q_node.length,sizeof(char));
/* q_node.content = temp_buffer; */
if (q_node.content != NULL) {
/* === Modify by Jason, 97.8.19 === */
if (node->format == 1) /* default stx & etx */
memcpy(q_node.content,msg_buf+1,q_node.length); /* Excluded STX */
else
memcpy(q_node.content,msg_buf,q_node.length); /* do not excluded STX */
/* ================================ */
if (!CAPIEnqueue(&q_node)) {
sprintf(temp_buffer,"node %s: can not put packet into queue",node->name);
(*record_err)(temp_buffer);
}
free(q_node.content); /* free the content memory */
}
else {
sprintf(temp_buffer,"node %s: packet received, but out of memory",node->name);
(*record_err)(temp_buffer);
}
node->head = head1 + 1; /* update head pointer */
node->head %= MAX_TCP_STREAM_BUFFER;
}/* end if found STX */
else /* not found STX but found end_marker */
// (*record_err)("CAPIProcessStream:Not found STX but found end_marker");
/* Add by Jason, 97.12.27
When reach ETX, break for statement, ending search in rcv buffer */
break;
}/* end found end_marker */
++head1;
head1 %= MAX_TCP_STREAM_BUFFER;
if (head1 == node->tail) break;
}/* end for */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -