pjqblues
C++博客
首页
新随笔
联系
聚合
管理
公告
<
2024年8月
>
日
一
二
三
四
五
六
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
统计
随笔 - 9
文章 - 13
评论 - 3
引用 - 0
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
(1)
给我留言
查看公开留言
查看私人留言
随笔分类
c++(1)
(rss)
随笔档案
2007年10月 (2)
2007年1月 (1)
2006年12月 (1)
2006年11月 (2)
2006年9月 (1)
2006年8月 (2)
文章分类
c++
(rss)
crack
(rss)
文章档案
2007年6月 (1)
2006年12月 (1)
2006年9月 (6)
2006年8月 (5)
搜索
最新评论
1. re: offsetof 解析
评论内容较长,点击标题查看
--XXX
2. re: offsetof 解析
补充一下,size_t是unsigned int。
--read more books
3. re: 上海印象
哈哈,顶!
--周星星
阅读排行榜
1. offsetof 解析(4187)
2. 使用标准C++的类型转换符:static_cast、dynamic_cast、reinterdivt_cast、和const_cast(3160)
3. com中以结构体作为接口参数(949)
4. Getting an (ATL) ActiveX control to print from Office Applications(505)
5. 转===如何用ATL创建ActiveX控件(牛人翻译的)(499)
评论排行榜
1. offsetof 解析(2)
2. 上海印象(1)
3. 使用标准C++的类型转换符:static_cast、dynamic_cast、reinterdivt_cast、和const_cast(0)
4. 2006年世界顶级杀毒软件排名(0)
5. com中以结构体作为接口参数(0)
一个socket实例===转
//
TCP的socket连接示例
//
Saturday, 4. March 2006, 05:35:49
/**/
/*
Socket, TCP, 异步
tp://www.zeali.net/blog/entry.php?id=13
用C实现的TCP socket连接/读/写操作。采用fcntl设置非阻塞式连接以实现connect超时处理;采用select方法来设置socket读写超时。此示例可被编译运行于Windows/unix系统。
源文件connector.c
原来的代码在windows下编译不通过,今天qzj问起才发现。因为加了异步的处理,没有对这部分代码进行兼容性处理。本着做学问一丝不苟嘀精神,重新修改了一下源代码。以下代码在VC++6和linux下编译执行通过
同时mark几个有用的url:
http://people.web.psi.ch/rohrer_u/sample1.htm
Demo program for remote CAMAC access via TCP/IP
http://www.lsword.net/code/list.asp?id=1383
将Socket应用程序从Unix向Windows移植中应注意的几点问题
*/
/**/
/*
* 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
<
stdio.h
>
#include
<
stdlib.h
>
#include
<
string
.h
>
#include
<
stdarg.h
>
#include
<
errno.h
>
#include
<
fcntl.h
>
#ifdef WIN32
#include
<
winsock2.h
>
#else
#include
<
unistd.h
>
#include
<
sys
/
types.h
>
#include
<
sys
/
socket.h
>
#include
<
sys
/
ioctl.h
>
#include
<
netinet
/
in
.h
>
#include
<
arpa
/
inet.h
>
#include
<
netdb.h
>
#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
char
buf[BUFSIZE];
static
char
i_host[MAX_STRING_LEN];
/**/
/*
site name
*/
static
char
i_port[MAX_STRING_LEN];
/**/
/*
port number
*/
void
err_doit(
int
errnoflag,
const
char
*
fmt, va_list ap);
void
err_quit(
const
char
*
fmt,
);
int
tcp_connect(
const
char
*
host,
const
unsigned
short
port);
void
print_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,
int
sec,
int
usec,
short
x)
{
int
st
=
errno;
struct
timeval to;
fd_set fs;
to.tv_sec
=
sec;
to.tv_usec
=
usec;
FD_ZERO(
&
fs);
FD_SET(s,
&
fs);
switch
(x)
{
case
READ_STATUS:
st
=
select(s
+
1
,
&
fs,
0
,
0
,
&
to);
break
;
case
WRITE_STATUS:
st
=
select(s
+
1
,
0
,
&
fs,
0
,
&
to);
break
;
case
EXCPT_STATUS:
st
=
select(s
+
1
,
0
,
0
,
&
fs,
&
to);
break
;
}
return
(st);
}
int
tcp_connect(
const
char
*
host,
const
unsigned
short
port)
{
unsigned
long
non_blocking
=
1
;
unsigned
long
blocking
=
0
;
int
ret
=
0
;
char
*
transport
=
"
tcp
"
;
struct
hostent
*
phe;
/**/
/*
pointer to host information entry
*/
struct
protoent
*
ppe;
/**/
/*
pointer to protocol information entry
*/
struct
sockaddr_in sin;
/**/
/*
an Internet endpoint address
*/
SOCKET s;
/**/
/*
socket descriptor and socket type
*/
int
error;
#ifdef WIN32
{
WORD wVersionRequested;
WSADATA wsaData;
int
err;
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);
else
if
( (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
<
0
)
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, (
struct
sockaddr
*
)
&
sin,
sizeof
(sin))
==
-
1
)
{
struct
timeval 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))
{
int
len
=
sizeof
(error);
//
下面的一句一定要,主要针对防火墙
if
(getsockopt(s, SOL_SOCKET, SO_ERROR, (
char
*
)
&
error,
&
len)
<
0
)
goto
error_ret;
if
(error
!=
0
)
goto
error_ret;
}
else
goto
error_ret;
//
timeout or error happen
}
else
goto
error_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);
}
return
s;
}
void
err_doit(
int
errnoflag,
const
char
*
fmt, va_list ap)
{
int
errno_save;
char
buf[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.
*/
void
err_quit(
const
char
*
fmt,
)
{
va_list ap;
va_start(ap, fmt);
err_doit(
0
, fmt, ap);
va_end(ap);
exit(
1
);
}
#ifdef WIN32
char
*
optarg;
char
getopt(
int
c,
char
*
v[],
char
*
opts)
{
static
int
now
=
1
;
char
*
p;
if
(now
>=
c)
return
EOF;
if
(v[now][
0
]
==
'
-
'
&&
(p
=
strchr(opts, v[now][
1
])))
{
optarg
=
v[now
+
1
];
now
+=
2
;
return
*
p;
}
return
EOF;
}
#else
extern
char
*
optarg;
#endif
#define
required(a) if (!a) { return -1; }
int
init(
int
argc,
char
*
argv[])
{
char
c;
//
int i,optlen;
//
int slashcnt;
i_host[
0
]
=
'
\0
'
;
i_port[
0
]
=
'
\0
'
;
while
((c
=
getopt(argc, argv,
"
h:?
"
))
!=
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
;
return
1
;
}
void
print_usage()
{
char
*
usage[]
=
{
"
Usage:
"
,
"
-h host name
"
,
"
-p port
"
,
"
example:
"
,
"
-h 127.0.0.1 -p 4001
"
,
}
;
int
i;
for
(i
=
0
; i
<
sizeof
(usage)
/
sizeof
(
char
*
); i
++
)
printf(
"
%s\n
"
, usage);
return
;
}
int
main(
int
argc,
char
*
argv[])
{
SOCKET fd;
int
n;
/**/
/*
parse command line etc
*/
if
(init(argc, argv)
<
0
)
{
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
return
0
;
}
posted on 2006-09-22 15:24
blues
阅读(2599)
评论(0)
编辑
收藏
引用
只有注册用户
登录
后才能发表评论。
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
网站导航:
博客园
IT新闻
BlogJava
知识库
博问
管理