Win Socket网络编程

本文介绍了一个基于Win Socket的网络编程示例,包括服务器和客户端的实现。通过详细讲解关键API函数,如WSAStartup、socket、bind等,帮助读者理解如何进行TCP连接的建立与数据的收发。

Win Socket网络编程

原料:#include <winsock2.h>

关键API函数:

1.int WSAStartup( wVersionRequested, &wsaData );

  Description:   搜索、绑定相应的Socket库

  Input parameters: wVersionRequested —— WinSocket版本

                    wsaData —— 指向WinSocket资料的指针

  Return Value: 0      if successful;

                Error  if failed.

2.int WSACleanup (void); 

  Description: 解除Socket库绑定并释放Socket库所占系统资源

 

3.SOCKET PASCAL FAR socket(int af,int type,int procotol);

  Description: 创建套接字
 Input parameters:af —— 通信发生的区域
                   type —— 要建立的套接字类型
                   procotol —— 使用的特定协议

4.int bind(SOCKET s, const struct sockaddr* name, int namelen);功能:将套接字地址与所创建的套接字号联系起来。
参数:第一个参数,指定需要绑定的套接字;

   第二个参数,指定该套接字的本地地址信息

   第三个参数,指定该网络协议地址的长度

5.int listen(SOCKET s, int backlog);

// 第一个参数,指定需要设置的套接字

// 第二个参数,等待连接队列的最大长度

6.SOCKET accept( SOCKET s,struct sockaddr* addr,int* addrlen);

// 第一个参数,接收一个处于监听状态下的套接字

// 第二个参数,sockaddr用于保存客户端地址的信息

// 第三个参数,用于指定这个地址的长度

// 返回监听状态下的套接字通信的套接字

7.int send( SOCKET s,  const char* buf,  int len,  int flags);

// 第一个参数,需要发送信息的套接字

// 第二个参数,包含了需要被传送的数据

// 第三个参数,buffer的数据长度

// 第四个参数,一些传送参数的设置

8.int recv(  SOCKET s,  char* buf,  int len,  int flags);

// 第一个参数,建立连接后的套接字,

// 第二个参数,接收数据

// 第三个参数,接收数据的长度,

// 第四个参数,一些传送参数的设置

9.int connect(int sockfd,struct sockaddr * serv_addr,int addrlen);
用于客户端建立tcp连接。

 

//参数:sockfd:标识一个套接字。
//serv_addr:套接字s想要连接的主机地址和端口号。
//addrlen:name缓冲区的长度。

10.closesocket(SOCKET s);//关闭套接字

代码如下:

1.服务器程序

//Sever.cpp
#include <iostream>
#include <cstdio>
#include <Winsock2.h>

using namespace std;

int main()
{   // 加载socket动态链接库(dll)
	WORD wVersionRequested;//使用的WinSock版本号
	WSADATA wsaData;       //Windows Socket资料
	int err;               //WSAStartup函数返回值
	wVersionRequested = MAKEWORD( 2, 2 );           //使用WinSock2.2版本
	err = WSAStartup( wVersionRequested, &wsaData );//绑定WinSocket动态库
	if ( err != 0 )
	{
		cout<<"Error:socket动态链接库绑定失败!"<<endl;
		return -1;
	}
	if ( LOBYTE( wsaData.wVersion ) != 2 ||	HIBYTE( wsaData.wVersion ) != 2 )
	{                 // 检查低字节=2?高字节=2?确定是否为请求的2.2版本
		WSACleanup( );// 否则的话,调用WSACleanup()清除信息,解除库绑定
		return -1;
	}
	SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);    //创建套接字
	SOCKADDR_IN addrSrv;    //地址结构
	addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(6000);
	bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));//连接套接字
	listen(sockSrv, 10);    //通知TCP服务器准备好接收连接
	SOCKADDR_IN  addrClient;//客户端地址信息
	int len = sizeof(SOCKADDR);
	while(true)
	{   //不断等待客户端请求的到来
		SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);
		char sendBuf[100];              //发送信息字符缓冲区
		sprintf(sendBuf, "服务器SEVER已连接...\n"),inet_ntoa(addrClient.sin_addr);
		printf("客户端IP地址:%s\n",inet_ntoa(addrClient.sin_addr));
		send(sockConn, sendBuf, strlen(sendBuf)+1, 0);//向客户端发送信息
		char recvBuf[100];              //接收信息字符缓冲区
		recv(sockConn, recvBuf, 100, 0);//从客户端接收信息
		printf("%s\n", recvBuf);        //显示客户端发送的信息
		char * sockConnName = "Client";
		printf("我们可以聊五句话");
		int n = 5;
		while(n--){
			printf("还剩%d次:\n", n+1);
			char recvBuf[100];
			recv(sockConn, recvBuf, 100, 0);
			printf("%s Says: %s\n", sockConnName, recvBuf);		// 接收信息

			char talk[100];
			printf("Please enter what you want to say next(\"quit\"to exit):");
			gets(talk);
			send(sockConn, talk, strlen(talk)+1, 0);			// 发送信息
			printf("\n");
		}
		printf("\nEnd talking... \n");
		closesocket(sockConn);//关闭套接字
	}

	printf("\n");
	system("pause");
	return 0;
}
2.客户端程序
// client.cpp
#include <iostream>
#include <cstdio>
#include <Winsock2.h>
using namespace std;
int main()
{   //加载socket动态链接库(dll)
	WORD wVersionRequested;//使用的WinSock版本号
	WSADATA wsaData;       //Windows Socket资料
	int err;               //WSAStartup函数返回值
	wVersionRequested = MAKEWORD( 2, 2 );           //使用WinSock2.2版本
	err = WSAStartup( wVersionRequested, &wsaData );//绑定WinSocket动态库
	if ( err != 0 )
	{
		cout<<"Error:socket动态链接库绑定失败!"<<endl;
		return -1;
	}
	if ( LOBYTE( wsaData.wVersion ) != 2 ||	HIBYTE( wsaData.wVersion ) != 2 )
	{                 // 检查低字节=2?高字节=2?确定是否为请求的2.2版本
		WSACleanup( );// 否则的话,调用WSACleanup()清除信息,解除库绑定
		return -1;
	}
	SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr = inet_addr("10.22.32.67");//本地IP地址:10.22.32.67
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(6000);
	err=connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));//建立TCP连接
    if ( err != 0 )
	{
		cout<<"Error:TCP连接失败!"<<endl;
		return -1;
	}
	char recvBuf[100];
	recv(sockClient, recvBuf, 100, 0);
	printf("%s\n", recvBuf);

	send(sockClient,"客户端Client已连接...\n", strlen("客户端Client已连接...\n")+1, 0);
	printf("我们可以聊五句话");
	int n = 5;
	do{
		printf("\n还剩%d次:", n);
		char talk[100];
		printf("\nPlease enter what you want to say next(\"quit\"to exit):");
		gets(talk);
		send(sockClient, talk, strlen(talk)+1, 0);			// 发送信息

		char recvBuf[100];
		recv(sockClient, recvBuf, 100, 0);
		printf("%s Says: %s\n", "Server", recvBuf);		// 接收信息
	}while(--n);

	printf("End linking...\n");
	closesocket(sockClient);
	WSACleanup();	// 终止对套接字库的使用

	printf("\n");
	system("pause");
	return 0;
}







Windows Sockets网络编程》是WindowsSockets网络编程领域公认的经典著作,由Windows Sockets2.0规范解释小组负责人亲自执笔,权威性毋庸置疑。它结合大量示例,对WindowsSockets规范进行了深刻地解读,系统讲解了WindowsSockets网络编程及其相关的概念、原理、主要命令、操作模式,以及开发技巧和可能的陷阱,从程序员的角度给出了大量的建议和最佳实践,是学习WindowsSockets网络编程不可多得的参考书。   全书分为三部分:第一部分(第1~6章),提供了翔实的背景知识和框架方面的概念,借助于此框架,读者可理解WinSock的具体细节,包括WindowsSockets概述、OSI网络参考模型、TCP/IP协议簇中的协议和可用的服务、WinSock网络应用程序的框架及其工作机制、WinSock的三种操作模式、socket通信机制等;第二部分(第7~12章),以FTP客户端实例为基础介绍了函数实例库,还介绍了客户端程序、服务器程序和DLL中间构件及它们的相应函数,并涵盖socket命令和选项及移植BSDSockets相关事项等;第三部分(第13~17章),介绍了应用程序调试技术和工具,针对应用编程中的陷阱的建议和措施,WinSockAPI的多种操作系统平台,WinSock规范的可选功能和WinSock规范2.0中的所有新功能。 译者序 序 前言 第1章 Windows Sockets概述 1.1 什么是Windows Sockets 1.2 Windows Sockets的发展历史 1.3 Windows Sockets的优势 1.3.1 Windows Sockets是一个开放的标准 1.3.2 Windows Sockets提供源代码可移植性 1.3.3 Windows Sockets支持动态链接 1.3.4 Windows Sockets的优点 1.4 Windows Sockets的前景 1.5 结论 第2章 Windows Sockets的概念 2.1 OSI网络模型 2.2 WinSock网络模型 2.2.1 信息与数据 2.2.2 应用协议 2.3 WinSock中的OSI层次 2.3.1 应用层 2.3.2 表示层 2.3.3 会话层 2.3.4 传输层 2.3.5 网络层 2.3.6 数据链路层 2.3.7 物理层 2.4 模块化的层次框 2.5 服务和协议 2.6 协议和API 第3章 TCP/IP协议服务 3.1 什么是TCP/IP 3.2 TCP/IP的发展历史 3.3 传输服务 3.3.1 无连接的服务:UDP 3.3.2 面向连接的服务:TCP 3.3.3 传输协议的选择:UDP与TCP的对比 3.4 网络服务 3.4.1 IP服务 3.4.2 ICMP服务 3.5 支持协议和服务 3.5.1 域名服务 3.5.2 地址解析协议 3.5.3 其他支持协议 3.6 TCP/IP的发展前景 第4章 网络应用程序工作机制 4.1 客户端-服务器模型 4.2 网络程序概览 4.3 socket的打开 4.4 socket的命名 4.4.1 sockaddr结构 4.4.2 sockaddr_in结构 4.4.3 端口号 4.4.4 本地IP地址 4.4.5 什么是socket名称 4.4.6 客户端socket名称是可选的 4.5 与另一个socket建立关联 4.5.1 服务器如何准备建立关联 4.5.2 客户端如何发起一个关联 4.5.3 服务器如何完成一个关联 4.6 socket之间的发送与接收 4.6.1 在“已连接的”socket上发送数据 4.6.2 在“无连接的”socket上发送数据 4.6.3 接收数据 4.6.4 socket解复用器中的关联 4.7 socket的关闭 4.7.1 closesocket 4.7.2 shutdown 4.8 客户端和服务器概览 第5章 操作模式 5.1 什么是操作模式 5.1.1 不挂机,等待:阻塞 5.1.2 挂机后再拨:非阻塞 5.1.3 请求对方回拨:异步 5.2 阻塞模式 5.2.1 阻塞socket 5.2.2 阻塞函数 5.2.3 伪阻塞的问题 5.2.4 阻塞钩子函数 5.2.5 阻塞情境 5.2.6 撤销阻塞操作 5.2.7 阻塞操作中的超时 5.2.8 无最少接收限制值 5.2.9 代码示例 5.3 非阻塞模式 5.3.1 怎样使socket成为非阻塞的 5.3.2 成功与失败不是绝对的 5.3.3 探询而非阻塞 5.3.4 显式地避让 5.3.5 代码示例 5.4 异步模式 5.4.1 认识异步函数 5.4.2 撤销异步操作 5.4.3 代码示例 5.4.4 AU_T
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值