/*
* on Unix:
* cc -c connector.c
* cc -o connector connector.o
*
* on Windows NT:
* open connector.c in Visual Studio
* press 'F7' to link -- a project to be created
* add wsock32.lib to the link section under project setting
* press 'F7' again
*
* running:
* type 'connector' for usage
*/
#include
#include
#include
#include
#include
#include
#ifdef WIN32
#include
#else
#include
#include
#include
#include
#include
#include
#include
#endif
#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif
#define MAX_STRING_LEN 1024
#define BUFSIZE 2048
#ifndef WIN32
#define SOCKET int
#else
#define errno WSAGetLastError()
#define close(a) closesocket(a)
#define write(a, b, c) send(a, b, c, 0)
#define read(a, b, c) recv(a, b, c, 0)
#endif
charbuf[BUFSIZE];
staticchari_host[MAX_STRING_LEN];/* site name */
staticchari_port[MAX_STRING_LEN];/* port number */
voiderr_doit(interrnoflag,constchar*fmt,va_listap);
voiderr_quit(constchar*fmt, ...);
inttcp_connect(constchar*host,constunsignedshortport);
voidprint_usage();
//xnet_select x defines
#define READ_STATUS 0
#define WRITE_STATUS 1
#define EXCPT_STATUS 2
/*
s - SOCKET
sec - timeout seconds
usec - timeout microseconds
x - select status
*/
SOCKET xnet_select(SOCKET s, intsec,intusec,shortx)
{
intst = errno;
structtimeval to;
fd_set fs;
to.tv_sec = sec;
to.tv_usec = usec;
FD_ZERO(&fs);
FD_SET(s, &fs);
switch(x){
caseREAD_STATUS:
st = select(s+1, &fs, 0, 0, &to);
break;
caseWRITE_STATUS:
st = select(s+1, 0, &fs, 0, &to);
break;
caseEXCPT_STATUS:
st = select(s+1, 0, 0, &fs, &to);
break;
}
return(st);
}
inttcp_connect(constchar*host,constunsignedshortport)
{
unsigned longnon_blocking = 1;
unsigned longblocking = 0;
intret = 0;
char* transport ="tcp";
structhostent *phe;/* pointer to host information entry */
structprotoent *ppe;/* pointer to protocol information entry*/
structsockaddr_in sin;/* an Internet endpoint address */
SOCKET s; /* socket descriptor and socket type */
interror;
#ifdef WIN32
{
WORDwVersionRequested;
WSADATA wsaData;
interr;
wVersionRequested = MAKEWORD( 2, 0 );
err = WSAStartup( wVersionRequested, &wsaData );
if( err != 0 ) {
/* Tell the user that we couldn't find a usable */
/* WinSock DLL. */
printf("can't initialize socket library\n");
exit(0);
}
}
#endif
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
if((sin.sin_port = htons(port)) == 0)
err_quit("invalid port \"%d\"\n", port);
/* Map host name to IP address, allowing for dotted decimal */
if( phe = gethostbyname(host) )
memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);
elseif( (sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE )
err_quit("can't get \"%s\" host entry\n", host);
/* Map transport protocol name to protocol number */
if( (ppe = getprotobyname(transport)) == 0)
err_quit("can't get \"%s\" protocol entry\n", transport);
/* Allocate a socket */
s = socket(PF_INET, SOCK_STREAM, ppe->p_proto);
if(s
err_quit("can't create socket: %s\n", strerror(errno));
/* Connect the socket with timeout */
#ifdef WIN32
ioctlsocket(s,FIONBIO,&non_blocking);
#else
ioctl(s,FIONBIO,&non_blocking);
#endif
//fcntl(s,F_SETFL, O_NONBLOCK);
if(connect(s, (structsockaddr *)&sin,sizeof(sin)) == -1){
structtimeval tv;
fd_set writefds;
// 设置连接超时时间
tv.tv_sec = 10; // 秒数
tv.tv_usec = 0; // 毫秒
FD_ZERO(&writefds);
FD_SET(s, &writefds);
if(select(s+1,NULL,&writefds,NULL,&tv) != 0){
if(FD_ISSET(s,&writefds)){
intlen=sizeof(error);
//下面的一句一定要,主要针对防火墙
if(getsockopt(s, SOL_SOCKET, SO_ERROR, (char*)&error, &len)
gotoerror_ret;
if(error != 0)
gotoerror_ret;
}
else
gotoerror_ret;//timeout or error happen
}
elsegotoerror_ret; ;
#ifdef WIN32
ioctlsocket(s,FIONBIO,&blocking);
#else
ioctl(s,FIONBIO,&blocking);
#endif
}
else{
error_ret:
close(s);
err_quit("can't connect to %s:%d\n", host, port);
}
returns;
}
voiderr_doit(interrnoflag,constchar*fmt,va_listap)
{
interrno_save;
charbuf[MAX_STRING_LEN];
errno_save = errno;
vsprintf(buf, fmt, ap);
if(errnoflag)
sprintf(buf + strlen(buf), ": %s", strerror(errno_save));
strcat(buf, "\n");
fflush(stdout);
fputs(buf, stderr);
fflush(NULL);
return;
}
/* Print a message and terminate. */
voiderr_quit(constchar*fmt, ...)
{
va_listap;
va_start(ap, fmt);
err_doit(0, fmt, ap);
va_end(ap);
exit(1);
}
#ifdef WIN32
char*optarg;
chargetopt(intc,char*v[],char*opts)
{
staticintnow = 1;
char*p;
if(now >= c)returnEOF;
if(v[now][0] =='-'&& (p = strchr(opts, v[now][1]))) {
optarg = v[now+1];
now +=2;
return*p;
}
returnEOF;
}
#else
externchar*optarg;
#endif
#define required(a) if (!a) { return -1; }
intinit(intargc,char*argv[])
{
charc;
//int i,optlen;
//int slashcnt;
i_host[0] = '\0';
i_port[0] = '\0';
while((c = getopt(argc, argv,"h:p:?")) != EOF) {
if(c =='?')
return-1;
switch(c) {
case'h':
required(optarg);
strcpy(i_host, optarg);
break;
case'p':
required(optarg);
strcpy(i_port, optarg);
break;
default:
return-1;
}
}
/*
* there is no default value for hostname, port number,
* password or uri
*/
if(i_host[0] =='\0'|| i_port[0] =='\0')
return-1;
return1;
}
voidprint_usage()
{
char*usage[] =
{
"Usage:",
" -h host name",
" -p port",
"example:",
" -h 127.0.0.1 -p 4001",
};
inti;
for(i = 0; i
printf("%s\n", usage[i]);
return;
}
intmain(intargc,char*argv[])
{
SOCKET fd;
intn;
/* parse command line etc ... */
if(init(argc, argv)
print_usage();
exit(1);
}
buf[0] = '\0';
/* pack the info into the buffer */
strcpy(buf, "HelloWorld");
/* make connection to the server */
fd = tcp_connect(i_host, (unsigned short)atoi(i_port));
if(xnet_select(fd, 0, 500, WRITE_STATUS)>0){
/* send off the message */
write(fd, buf, strlen(buf));
}
else{
err_quit("Socket I/O Write Timeout %s:%s\n", i_host, i_port);
}
if(xnet_select(fd, 3, 0, READ_STATUS)>0){
/* display the server response */
printf("Server response:\n");
n = read(fd, buf, BUFSIZE);
buf[n] = '\0';
printf("%s\n", buf);
}
else{
err_quit("Socket I/O Read Timeout %s:%s\n", i_host, i_port);
}
close(fd);
#ifdef WIN32
WSACleanup();
#endif
return0;
}