介绍:
WinSock(Windows Sockets)API是一个微软的windows系统接口编程库。它最初是基于Berkeley sockets。但是微软做了一些相应的改动。这里我试图简单的介绍一下WinSock的编程技术,假定你已经开发过一些网络程序不论是什么操作系统。
如果你只有一台机器,不用担心,你仍然可以进行WinSock编程。你可以使用本地的地址localhost作为IP地址通常是127.0.0.1。如果你有你特TCP的服务器在机器上运行,还可以运行一个客户端程序在同一台电脑上。
简单的TCP服务器:
这里我要通过一个简单的TCP服务器向你介绍一下WinSock,我会一步一步讲。但在开始之前,你先要完成一点任务,然后在真正开始WinSock编程。
开始要用VC++ 6.0App Wizard建立一个 Win32的控制台程序。在这里选择support for MFC选项。
打开stdafx.h文件,添加#include <winsock2.h> 还有#include conio.h和iostream.h。使用Project-Settings-Link在其中的library modules list中添加ws2_32.lib。
以下是主程序:
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
cout << "Press ESCAPE to terminate program/r/n";
AfxBeginThread(ServerThread,0);
while(_getch()!=27);
return nRetCode;
}
主程序是用来建立一个线程然后循环调用_getch()。_getch()一直等待直到得到一个键盘输入的字符值。当得到ASCII值是27时返回,因为27的ASCII码是ESCAPE键。你也许知道即使我按了ESCAPE,开始建立的线程也不会结束。这根本不用担心。当main() 函数返回该线程将关闭同时我在开始建立的那个线程也会关闭。
服务器线程函数:
我要做的是列出服务器的线程,然后用注释解释每一行代码。首先TCP服务器是这样工作的。它侦听20248端口,这个可能凑巧和其它代码的冲突。当一个客户端连接时,服务器将返回一个信息到客户端给出IP地址然后开始在20248端口上接收数据。在控制台上同时打印一行连接的客户端的IP。当然你觉得写这么个程序毫无意义。你也许觉得它和windows系统中的SNDREC32.EXE程序一样没意义。如果这样我会觉得你太挑剔。
CollapseUINT ServerThread(LPVOID pParam)
{
cout << "Starting up TCP server/r/n";
//一个SOCKET定义,其实是unsigned int的typedef
//在Unix系统中socket句柄也是这样的类型
//因为这不可能在windows下从新定义类型所以一个统一的SOCKET类型被定义了
SOCKET server;
//WSADATA是一个在WSAStartup调用中填充数据的结构
WSADATA wsaData;
//sockaddr_in指定TCP/IP的socket地址。该协议的结构非常熟悉
sockaddr_in local;
//WSAStartup引入,第一个参数指定WinSock的版本,然后在程序中使用。
int wsaret=WSAStartup(0x101,&wsaData);
//WSAStartup在成功建立后返回0,如果不是就结束程序
if(wsaret!=0)
{
return 0;
}
//现在非常熟悉的sockaddr_in结构参数
local.sin_family=AF_INET; //Address family
local.sin_addr.s_addr=INADDR_ANY; //Wild card IP address
local.sin_port=htons((u_short)20248); //port to use
//用socket函数建立SOCKET
server=socket(AF_INET,SOCK_STREAM,0);
//如果失败则退出程序
if(server==INVALID_SOCKET)
{
return 0;
}
//将建立的SOCKET帮定到sockaddr_in
if(bind(server,(sockaddr*)&local,sizeof(local))!=0)
{
return 0;
}
//开始侦听
if(listen(server,10)!=0)
{
return 0;
}
//再建立接受已经连接的客户端的SOCKET
SOCKET client;
sockaddr_in from;
int fromlen=sizeof(from);
while(true)//we are looping endlessly
{
char temp[512];
//当有数据时接受连接客户端
client=accept(server,
(struct sockaddr*)&from,&fromlen);
sprintf(temp,"Your IP is %s/r/n",inet_ntoa(from.sin_addr));
//向客户端发送一个字符串
send(client,temp,strlen(temp),0);
cout << "Connection from " << inet_ntoa(from.sin_addr) <<"/r/n";
//关闭连接客户端的socket
closesocket(client);
}
//关闭服务端socket
closesocket(server);
//通常调用WSACleanup来结束是比较安全的
WSACleanup();
return 0;
}
测试输出:
在服务端得到如下输出结果:
E:/work/Server/Debug>server
Press ESCAPE to terminate program
Starting up TCP server
Connection from 203.200.100.122
Connection from 127.0.0.1
E:/work/Server/Debug>
以下是客户段的输出结果:
nish@sumida:~$ telnet 202.89.211.88 20248
Trying 202.89.211.88...
Connected to 202.89.211.88.
Escape character is '^]'.
Your IP is 203.200.100.122
Connection closed by foreign host.
nish@sumida:~$
结束:
这样,你知道了怎样建立一个简单的TCP服务器了。如果更深一步我会介绍给你用 WinSock 建立更高级功能的程序。如果有人对该程序有疑问,请回复。