博文

转socket非阻塞模型(2008-08-24 11:09:00)

摘要:1、select 模型
int select(
int nfds,    //忽略,兼容Berkeley套接字
fd_set* readfds,   //可读套接字集合
fd_set* writefds,   //可写套接字集合
fd_set* exceptfds,   //指向套接字集合,检查错误
const struct timeval* timeout //超时时间,NULL为无限等待
);
typedef struct fd_set {
u_int fd_count;    //数组大小
SOCKET fd_array[FD_SETSIZE]; //socket数组
} 预定义的4个操作fd_set的常用宏:
FD_ZERO(*set) 初始化set为空,清空集合
FD_CLR(s,*set) 从set移除s
FD_ISSET(s,*set)检查s是否在set中,true-存在
FD_SET(s,*set) 添加s到set中 评价:
单线程可以处理多个socket,但是需要不断进行对select返回的结果进行检查,性能不高
2、WSAAsyncSelect 模型
异步Windows消息通知模型 非阻塞同步模型,先产生windows消息,然后进行操作,操作不完成不返回
int WSAAsyncselect(
SOCKET s,    //socket句柄
HWND hWnd,    //指定接受消息的窗口句柄
u_int wMsg,    //指定网络事件来到时接受到的消息ID
long lEvent    //指定哪些网络事件需要通知
);

lEvent可以取以下值的组合:
FD_READ   缓冲区有数据,可读
FD_WRITE 缓冲区变空,可写
FD_ACCEPT 有连接接入
FD_CONNECT 连接完成
......

阅读全文(3665) | 评论:0

转socket编程——技术实现(2008-08-23 21:20:00)

摘要:socket 实现 这几天都在玩socket了,有一点心得,贴出来与大家共赏,若有不妥或错误的地方,还请各位看官指点一二。 什么是socket?socket就是...,我在这里就不抄书了,有兴趣的同仁去查查书吧。
不过还要说一句,socket就是不同进程之间的一种通信方式。就象打电话是朋友之间的一种通信方式是一样。个人理解:所谓“通信”,就是相互之间发送数据。有人理解socket是不同计算机之间的一种通信方
式,这是不确切的。两个进程,不管是运行在同一台计算机上,还是运行在不同计算机上,都可通过
socket技术进行通信。 socket套接字的使用需要有网卡的支持,所以socket一般都被用来在不同机器之间通信,而如果在同一台计算机上的两个进程进行通信,通常采用效率更高的共享内存技术来实现。 两个进程之间进行通讯,就需要两个进程同时都在运行了(废话),在具体实现中,两个进程我们通常要区别对待,一个进程专门等待另一个进程给自己发消息,收到消息后进行处理,在把处理结果发送回去。我们把专门处理消息、提供服务的进程称为服务器端,把发送消息、请求处理的进程称为客户端。总体过程就是客户端发送一个消息给服务器端,服务器端进程收到消息进行处理,把处理结果发送给客户端。恩,就是这样。 还有一个问题,如果我现在有一个进程要跟另一台计算机上的某个进程进行socket通信,那在我这个进程中如何指定另一个进程呢?这里还需要说一下另一个概念——端口,如果把操作系统比作一座房子的话,那端口就是房子的窗口,是系统外界同系统内部进行通信的通道。在socket实现中,我们不进行另一个进程的指定,而是指定发送消息或接收消息的端口号。比如说现在进程A要给进程B发消息,我们会把消息发送到进程B所运行的计算机的端口N上,而进程B此时正在监视端口N,这样进程B就能收到进程A发送来的数据,同样进程B也把消息发送到该端口上,进程A也能从该端口收到进程B发送来的数据,当然,这需要客户端和服务器端关于端口号进行一个约定,即共同操作同一个端口。如果客户端把消息发送到端口N1上,而服务器端监视的是端口N2,那通信一定不能成功。端口号最大为65535,不能比这个再大了,但在我们自己的程序中尽量不要用小于1024的端口号,小于1024的端口好很多都被系统使用了,比如23被telnet所使用。 so......

阅读全文(2549) | 评论:0

转vc中socket编程步骤(2008-08-23 17:33:00)

摘要:vc中socket编程步骤 2008-06-08 11:19 [转]vc中socket编程步骤    sockets(套接字)编程有三种,流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM),原始套接字(SOCK_RAW);基于TCP的socket编程是采用的流式套接字。在这个程序中,将两个工程添加到一个工作区。要链接一个ws2_32.lib的库文件。

服务器端编程的步骤:

1:加载套接字库,创建套接字(WSAStartup()/socket());

2:绑定套接字到一个IP地址和一个端口上(bind());

3:将套接字设置为监听模式等待连接请求(listen());

4:请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept());

5:用返回的套接字和客户端进行通信(send()/recv());

6:返回,等待另一连接请求;

7:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。

服务器端代码如下:
#include <stdio.h>
#include <Winsock2.h>
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
  return;
}

if ( LOBYTE( wsaData.wVersion ) != 1 ||
         HIBYTE( wsaData.wVersion ) != 1 ) {
   WSAC......

阅读全文(4311) | 评论:0

转利用MFC的Csocket类实现网络通信(2008-08-20 21:21:00)

摘要:近年来,利用Internet进行网际间通讯,在WWW浏 览、FTP、Gopher这些常规服务,以及在网络电话、多媒体会议等这些对实时性要求严格 的应用中成为研究的热点,而且已经是必需的了。Windows环境下进行通讯程序设计的最基本方法是应用Windows Sockets实现进程间的通讯,为此微软提供了大量基于Windows Sockets的通讯API,如WinSockAPI、WinInetAPI和ISAPI,并一直致力于开发更快、 更容易的通讯API,将其和MFC集成在一起以使通讯编程越来越容易。本实例重点介绍使用MFC的CSocket类编写网络通讯程序的方法,并通过使用CSocket类实现了网络聊天程序。程序编译运行后的界面效果如图一所示:


图一、网络聊天程序界面效果图
  一、实现方法

  微软的MFC把复杂的WinSock API函数封装到类里,这使得编写网络应用程序更容易。CAsyncSocket类逐个封装了WinSock API,为高级网络程序员 提供了更加有力而灵活的方法。这个类基于程序员了解网络通讯的假设,目的是为了在MFC中使用WinSock,程序员有责任处理诸如阻塞、字节顺序和在Unicode与MBCS 间转换字符的任务。为了给程序员提供更方便的接口以自动处理这些任务,MFC给出 了CSocket类,这个类是由CAsyncSocket类继承下来的,它提供了比CAsyncSocket更高层的WinSock API接口。Csocket类和CsocketFile类可以与Carchive类一起合作来管理发送和接收的数据,这使管理数据收发更加便利。CSocket对象提供阻塞模式,这对于Carchive的同步操作是至关重要的。阻塞函数(如Receive()、Send()、ReceiveFrom()、SendTo() 和Accept())直到操作完成后才返回控制权,因此如果需要低层控制和高效率,就使用CasyncSock类;如果需要方便,则可使用Csocket类。

  一些网络应用程序(如网络电话、多媒体会议工具)对实时性要求非常强,要求能够直接应用WinSock发送和接收数据。为了充分利用MFC 的优势,首选方案应当是MFC中的CAsyncSocket类或CSocket类,这两个类......

阅读全文(3635) | 评论:0

vc 对P2P的思考(2008-06-04 10:38:00)

摘要: vc 对P2P的思考A向服务器发送请求包,服务器端获取IP和端口号(IP应该是10.10.10.10)  
  B向服务器发送请求包,服务器端获取IP和端口号(IP应该是20.20.20.20)  
  服务器向A发送B的IP和端口,B监听  
  或者服务器向B发送A的IP和端口,A监听  
  然后A和B连接成功后开始会话

如果无公网IP
NAT机制直接把IP和端口屏蔽,
现在的NAT机制大部分是IP和端口对于多连接是不变的(一个内网访问多个外网其IP和端口转了后都是同一个,和半克隆的NAT不同,他会重新修改端口).
well,这样就是点对点通讯原理,喜欢的话去编写一个QQ吧......

阅读全文(3121) | 评论:0

转TCP实现P2P通信、TCP穿越NAT的方法、TCP打洞(2008-04-11 16:27:00)

摘要:TCP实现P2P通信、TCP穿越NAT的方法、TCP打洞

作者:谢红伟 下载源代码

这个标题用了两个顿号三个名称,其实说得是同一个东西,只是网上有不同的说法罢了,另外好像还有人叫TCP打孔(我的朋友小妞听说后问“要打孔啊,要不要我帮你去借个电钻过来啊?”“~!·¥%……·!”)。 闲话少说,我们先看一下技术背景:
Internet的迅速发展以及IPv4 地址数量的限制使得网络地址翻译(NAT,Network Address Trans2lation)设备得到广泛应用。NAT设备允许处于同一NAT后的多台主机共享一个公网(本文将处于同一NAT后的网络称为私网,处于NAT前的网络称为公网) IP 地址。一个私网IP 地址通过NAT设备与公网的其他主机通信。公网和私网IP地址域,如下图所示:

广域网与私网示意图

一般来说都是由私网内主机(例如上图中“电脑A-01”)主动发起连接,数据包经过NAT地址转换后送给公网上的服务器(例如上图中的“Server”),连接建立以后可双向传送数据,NAT设备允许私网内主机主动向公网内主机发送数据,但却禁止反方向的主动传递,但在一些特殊的场合需要不同私网内的主机进行互联(例如P2P软件、网络会议、视频传输等),TCP穿越NAT的问题必须解决。网上关于UDP穿越NAT的文章很多,而且还有配套源代码,但是我个人认为UDP数据虽然速度快,但是没有保障,而且NAT为UDP准备的临时端口号有生命周期的限制,使用起来不够方便,在需要保证传输质量的应用上TCP连接还是首选(例如:文件传输)。
网上也有不少关于TCP穿越NAT(即TCP打洞)的介绍文章,但不幸我还没找到相关的源代码可以参考,我利用空余时间写了一个可以实现TCP穿越NAT,让不同的私网内主机建立直接的TCP通信的源代码。 这里需要介绍一下NAT的类型:
NAT设备的类型对于TCP穿越NAT,有着十分重要的影响,根据端口映射方式,NAT可分为如下4类,前3种NAT类型可统称为cone类型。
(1)全克隆( Full Cone) : NAT把所有来自相同内部IP地址和端口的请求映射到相同的外部IP地址和端口。任何一个外部主机均可通过该映射发送IP包到该内部主机。
(2)限制性克隆(Restricted ......

阅读全文(3356) | 评论:0

关于循环发送SOCKET问题(2008-01-25 11:38:00)

摘要:单线程,一直没考虑,所以容易死循环 特别是客户端需要服务端返回修改变量流程的情况 循环接收似乎不能实现。   也就是如果对话框不同之间用SOCKET就会出现这问题 烦!   解决方法是在功能项上直接 发送,接收,断SOCKET......

阅读全文(547) | 评论:0

第二章  socket编程原理(2007-08-21 09:52:00)

摘要:http://www.moon-soft.com/doc/5123.htm   第二章  socket编程原理
2.1  问题的引入
       UNIX系统的I/O命令集,是从Maltics和早期系统中的命令演变出来的,其模式为打开一读/写一关闭(open-write-read- close)。在一个用户进程进行I/O操作时,它首先调用“打开”获得对指定文件或设备的使用权,并返回称为文件描述符的整型数,以描述用户在打开的文件或设备上进行I/O操作的进程。然后这个用户进程多次调用“读/写”以传输数据。当所有的传输操作完成后,用户进程关闭调用,通知操作系统已经完成了对某对象的使用。        TCP/IP协议被集成到UNIX内核中时,相当于在UNIX系统引入了一种新型的I/O操作。UNIX用户进程与网络协议的交互作用比用户进程与传统的 I/O设备相互作用复杂得多。首先,进行网络操作的两个进程在不同机器上,如何建立它们之间的联系?其次,网络协议存在多种,如何建立一种通用机制以支持多种协议?这些都是网络应用编程界面所要解决的问题。        在UNIX系统中,网络应用编程界面有两类:UNIX  BSD的套接字(socket)和UNIX System V的TLI。由于Sun公司采用了支持TCP/IP的UNIX  BSD操作系统,使TCP/IP的应用有更大的发展,其网络应用编程界面──套接字(socket)在网络软件中被广泛应用,至今已引进微机操作系统 DOS和Windows系统中,成为开发网络应用软件的强有力工具,本章将要详细讨论这个问题。 2.2  套接字编程基本概念
       在开始使用套接字编程之前,首先必须建立以下概念。 2.2.1  网间进程通信
       进程通信的概念最初来源于单机系统。由于每个进程都在自己的地址范围内运行,为保证两个相互通信的......

阅读全文(2416) | 评论:0

VC++ TCP/IP 服务/客户程序源代码(2007-08-21 09:38:00)

摘要:http://blog.csdn.net/raymondtchang/archive/2007/05/05/1597191.aspx   //TCP
//服务器端程序
#include< stdio.h >
#include< stdlib.h >
#include< windows.h >
#include< winsock.h >
#include< string.h >

#pragma comment( lib, "ws2_32.lib" )

#define PORT 2046
#define BACKLOG 10
#define TRUE 1

void main( void )
{
int iServerSock;
int iClientSock;

char *buf = "hello, world!\n";

struct sockaddr_in ServerAddr;
struct sockaddr_in ClientAddr;

int sin_size;

WSADATA WSAData;

if( WSAStartup( MAKEWORD( 1, 1 ), &WSAData ) )//初始化
{
printf( "initializationing error!\n" );
WSACleanup( );
exit( 0 );
}

if( ( iServerSock = socket( AF_INET, SOCK_STREAM, 0 ) ) == INVALID_SOCKET )
{
printf( "创建套接字失败!\n" );
WSACleanup( );
exit( 0 );
}

ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons( PORT );//监视的端口号
ServerAddr.sin_addr.s_addr =......

阅读全文(7112) | 评论:0

TCP/IP网络通信程序设计(2007-08-20 17:41:00)

摘要:http://www.moon-soft.com/doc/1821.htm   TCP/IP网络通信程序设计 湖北大学数学与计算机科学学院(430062) 党德鹏 本文介绍了TCP/IP网络应用程序的面向对象设计方法,并给出了 用Visual C++4.2中MFC在Windows 95环境下开发的程序实例。 1 Sockets与Winsock 95 Winsock 95是在Unix Sockets及Windows Sockets基础上发展起 来的。Sockets原是BSD为了Unix支持互联网通信而设计的4.3BSD Uni x版本中的API,它采用客户-服务器模式的通信机制,使网络客户方和 服务器方通过Sockets实现网络之间的联接和数据交换;Win dows Soc kets描述定义了一个Microsoft Windows的网络编程界面,它为Window s TCP/IP 提供了一个BSD型套接字,除与4.3BSD Unix Sockets完全兼 容外,还包括一个扩充文件,通过一组附加的API实现Windows式(即事 件驱动)的编程风格;而Winsock 95则是在Microso ft Windows 95中 进行网络应用程序设计的接口。Windows 95在Internet支配域中的TC P /IP协议定义了Winsock 95网络编程规范,溶入了许多新特点。MFC 中提供了相应的CSock et类来实现网络通信。 2 Sockets编程原理 Sockets同时支持数据流Sockets和数据报Sockets。 下面是利用Socket进行通信连接的过程框图。其中图1是面向连 接的时序图,图2是无连接的时序图。 图1 图2 由图可以看出,客户与服务器的关系是不对称的。对于TCP C/S, 服务器首先启动,然后在某一时刻启动客户与服务器建立连接。服务 器与客户开始都必须调用socket()建立一个套接字socket,然后服务 器调用bind()将套接字与一个本地网络地址捆扎在一起,再调用liste n()使套接字处于一种被动的准备接收状态,同时规定它的请求队列长 度,之后服务器就可以调用accept()来接收客户连接。客户打开套接 ......

阅读全文(2694) | 评论:0