这个不是我原创的,在单位,不知道是哪个前辈所编写,基本可以当封装函数使用,呵呵
文件名 : sharefunc.c
在SCO UNIX ,红旗LINUX下编译测试通过,这个函数n_tcpsr只能收发定长的BUF,自己可以改成收发不定长的报文
#include <unixdef.h>
#include <gateway.h>
#include <gwapi.h>
#include <msqmani.h>
#include <pubfunc.h>
#include <errlog.h>
#include <fml32.h>
#include <atmi.h>
#include <starring_def.h>
#include <dataelem.h>
/* enhanced 'read'
* it'll try to read 'count' charaters until nothing leave and
* will not be interrupted by some unexpected signals
* if there's not 'count' bytes, it will return the amount it read
*/
size_t nn_read( int fd, char *buf, size_t count )
{
size_t bytes_read = 0;
int this_read;
while( bytes_read < count ) {
do
this_read = read( fd, buf, count - bytes_read );
while( this_read < 0 );
if( this_read <= 0 )
return bytes_read;
bytes_read += this_read;
buf += this_read;
}
return count;
}
/* please see the comment of 'n_read'
*/
size_t nn_write( int fd, char *buf, size_t count )
{
size_t bytes_write = 0;
int this_write;
while( bytes_write < count ) {
do
this_write = write( fd, buf, count - bytes_write );
while( this_write < 0 );
if( this_write <= 0 )
return bytes_write;
bytes_write += this_write;
buf += this_write;
}
return count;
}
void offtime_exit()
{
return;
}
int n_tcpsr( char *hostip, int hostport, /
char *buf, size_t wcnt, size_t rcnt, int offtime )
{
struct timeval tms;
fd_set fdset;
int sockfd,buflen,ret;
char *buffer;
if( ( sockfd = ns_init( hostip, hostport, 1 ) ) < 0 ) {
sprintf( buf, "连接服务[%s:%d]失败", hostip, hostport );
return -1;
}
memset( &tms, 0x0, sizeof(tms) );
tms.tv_sec = offtime;
tms.tv_usec = 0 ;
FD_ZERO( &fdset );
FD_SET( sockfd, &fdset );
buflen = wcnt > rcnt ? wcnt : rcnt;
buffer = (char *)malloc( buflen );
memset( buffer, 0x0, sizeof( buffer ) );
(void)memcpy( buffer, buf, wcnt );
signal( SIGALRM, offtime_exit );
alarm ( offtime );
if( ( ret = nn_write( sockfd, buffer, wcnt ) ) != wcnt ) {
sprintf( buf, "发送数据长度出错(%d)", ret );
free( buffer );
close( sockfd );
return -2;
}
if( !select( sockfd+1, &fdset, NULL, NULL, &tms ) ) {
sprintf( buf, "等待网络返回超时" );
free( buffer );
close( sockfd );
return -4;
}
memset( buffer, 0x0, sizeof(buffer) );
if( ( ret = nn_read( sockfd, buffer, rcnt ) ) != rcnt ) {
sprintf( buf, "接收数据长度出错(%d)", ret );
free( buffer );
close( sockfd );
return -3;
}
(void)memcpy( buf, buffer, rcnt );
free( buffer );
close( sockfd );
return 1;
}
/* AF_INET,SOCK_STREAM socket initialize
* flag=0: initialize server at port 'srvport'
* flag=1: connect to specified server
*/
ns_init( char *srvaddr, int srvport, int flag )
{
struct sockaddr_in server;
int sockfd;
if( ( sockfd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
return -1;
bzero( &server, sizeof(server) );
server.sin_family = AF_INET;
server.sin_port = htons( srvport );
if( !flag ) {
if( bind( sockfd, (struct sockaddr *)&server, sizeof(server) ) < 0 )
return -1;
if( listen( sockfd, 5 ) < 0 )
return -1;
}
else if( flag == 1 ) {
server.sin_addr.s_addr = inet_addr( srvaddr );
if( connect( sockfd, (struct sockaddr *)&server, sizeof(server) ) < 0 )
return -1;
}
return sockfd;
}
/* 'log' recorder
* format: first parameter( logfile ) --the file where log be recorded
second: log time
third,...( fmt,... ) -- like the 'fprintf' system call, but not allow to use the number
*/
void n_log( char *filename, char *fmt, ... )
{
tTime tt;
FILE *fp;
va_list ap;
char logfile[_POSIX_PATH_MAX],rtime[15],info[2048];
get_time( &tt );
sprintf( rtime, "%.4s%.2s%.2s%.2s%.2s%.2s", /
tt.year, tt.month, tt.day, /
tt.hour, tt.minute, tt.second );
sprintf( logfile, "%s%.8s", filename, rtime );
if( ( fp = fopen( logfile, "a" ) ) == NULL )
return;
memset( info, 0x0, sizeof(info) );
fprintf( fp, "[%.2s:%.2s:%.2s]/n", rtime+8, rtime+10, rtime+12 );
va_start( ap, fmt );
vsprintf( info, fmt, ap );
fprintf( fp, "%s/n", info );
fprintf( fp, "--------------------------------------------------/n/n" );
va_end( ap );
fclose( fp );
}