SOCKET客户端部分程序

这个不是我原创的,在单位,不知道是哪个前辈所编写,基本可以当封装函数使用,呵呵

文件名  :  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 );
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值