分享
 
 
 

Winsock程序设计入门(1)

王朝system·作者佚名  2006-05-27
窄屏简体版  字體: |||超大  

作者:Nishant S

原文链接:http://www.codeproject.com/internet/winsockintro01.asp

一、简单的TCP服务器

介绍

WinSock API是一套供Microsoft Windows操作系统使用的套接字程序库,它最初基于Berkeley套接字,但是其中加入了一些Microsoft的特殊改动。在这篇文章中,我要试着给你介绍如何使用WinSock来进行套接字程序设计,并假设你没有在任何操作系统上进行过网络编程的经验。

如果你只有一台单独的机器,那么不用着急,你仍然可以进行WinSock程序设计。你可以使用名为localhost的本地回环地址,它的IP地址是127.0.0.1。这样一来,如果你在机器上运行了一个TCP服务器,那么同一机器上的客户端程序就可以使用这个回环地址连接到服务器了。

简单的TCP服务器

在本文中,我将通过一个简单的TCP服务器来向你介绍WinSock,我们会一步一步地创建这个程序。但是,在我们开始之前,你还必须做一些事情,这样我们才能为开始我们的WinSock程序做好准备。

·首先,使用VC++ 6.0应用程序向导来创建一个Win32 console application。

·选择add support for MFC选项。

·打开stdafx.h文件,并添加这一行:#include <winsock2.h>。

·选择Project-Settings-Link,并在库模块列表中加入ws2_32.lib。

main函数

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;

}

我们在main()中所做的是开启一个线程,然后对一个_getch()调用进行循环。_getch()仅仅是等待一个键的按下,并返回这个读入字符的ASCII值。我们一直循环,直到返回27这个值为止——既然27是ESCAPE键的ASCII码。你可能想知道的是,即使我们按下了ESCAPE,我们开启的线程也还会是活动的状态。不用为这些事情担心,因为当main()返回的时候,进程就会被终止,主线程开启的线程也会被突然终止。

ServerThread函数

现在我所要做的事情就是把我们的ServerThread函数列出来,并使用代码的注释来解释相关的代码行做了些什么。我们的TCP服务器主要做的事情是监听端口20248,这个数字也就是我在Code Project的成员ID。这个过程中的事件是:当客户端连接的时候,服务器将会向客户端发回一条消息告知它的IP地址,然后关闭连接并继续接收20248端口的连接。它还会在运行的控制台上打印出连接来自的IP地址。总而言之,你可能会认为这是一个绝对没用的程序。事实上,你们中的有些人甚至可能会认为它和Windows中的SNDREC32.EXE一样没用。我说,你们也忒苛刻了吧。

UINT ServerThread(LPVOID pParam)

{

cout << "Starting up TCP server\r\n";

// SOCKET其实是unsigned int的一个typedef。

// 在Unix中,套接字句柄就像文件句柄一样,都是unsigned int。

// 既然在Windows下这些不是真的,那么我们就定义了一种新的数据类型,名为SOCKET。

SOCKET server;

// WSADATA是一个struct,WSAStartup的调用将会填充之。

WSADATA wsaData;

// sockaddr_in为TCP/IP套接字指定了套接字的地址。

// 其它的协议都使用相似的结构。

sockaddr_in local;

// WSAStartup为程序调用WinSock进行了初始化。

// 第一个参数指定了程序允许使用的WinSock规范的最高版本。

int wsaret=WSAStartup(0x101,&wsaData);

// 如果成功,WSAStartup返回零。

// 如果失败,我们就退出。

if(wsaret!=0)

{

return 0;

}

// 现在我们来为sockaddr_in结构赋值。

local.sin_family=AF_INET; // 地址族

local.sin_addr.s_addr=INADDR_ANY; // 网际IP地址

local.sin_port=htons((u_short)20248); // 使用的端口

// 由socket函数创建我们的SOCKET。

server=socket(AF_INET,SOCK_STREAM,0);

// 如果socket()函数失败,我们就退出。

if(server==INVALID_SOCKET)

{

return 0;

}

// bind将我们刚创建的套接字和sockaddr_in结构联系起来。

// 它主要使用本地地址及一个特定的端口来连接套接字。

// 如果它返回非零值,就表示出现错误。

if(bind(server,(sockaddr*)&local,sizeof(local))!=0)

{

return 0;

}

// listen命令套接字监听来自客户端的连接。

// 第二个参数是最大连接数。

if(listen(server,10)!=0)

{

return 0;

}

// 我们需要一些变量来保存客户端的套接字,因此我们在此声明之。

SOCKET client;

sockaddr_in from;

int fromlen=sizeof(from);

while(true) // 无限循环

{

char temp[512];

// accept()将会接收即将到来的客户端连接。

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";

// 关闭客户端套接字

closesocket(client);

}

// closesocket()关闭套接字,并释放套接字描述符。

closesocket(server);

// 最初这个函数也许有些用处,现在保留它只是为了向后兼容。

// 但是调用它可能会更安全,因为我相信某些实现会使用它来结束WS2_32.DLL的使用。

WSACleanup();

return 0;

}

测试

运行这个服务器,并在它运行的时候使用telnet来连接机器的20248端口。如果你是在同一台机器上使用,那么就连接到localhost。

示例输出

我们将会在服务器上看到这样的输出:

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服务器。在以后的文章中,我会给你一些更多的材料,你可以通过这些材料创建一个合适的TCP客户端。如果有谁对于编译这些代码有问题的话可以mail我,我会发给你一个压缩了的工程。谢谢您的阅读。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有