Winsock是Windows下网络编程的标准接口。使用Winsock编程的步骤一般是比较固定的。

首先要包含头文件#include <WinSock2.h>,同时要添加WS2_32.lib的链接:

#include <WinSock2.h>

#pragma comment(lib,"WS2_32")

每个 Winsock 应用程序必须加载相应版本的 Winsock DLL,一般通过WSAStartup函数实现,这个函数有两个功能,一是加载套接字库,二是进行套接字库的版本协商,也就是确定要使用的winsock版本。

函数原型如下:

int WSAAPI WSAStartup( __in WORD wVersionRequested,__out LPWSADATA lpWSAData );

每一个对 WSAStartup 的调用必须对应一个对 WSACleanup 的调用,这个函数释放

Winsock 库。

int WSAAPI WSACleanup( void );

下面通过一些简单的例子来说明winsock编程的流程:

基于TCP(面向连接)的socket编程

基于TCP的socket编程服务端程序流程如下:

  • 创建套接字(socket)
  • 绑定套接字到指定的IP和端口号(bind)
  • 设置套接字进入监听状态(listen)
  • 等待客户连接请求(accept)
  • 收发数据,进行通信(send/recv)
  • 关闭套接字

基于TCP的socket编程客户端程序流程如下:

  • 创建套接字(socket)
  • 向服务器发出连接请求(connect)
  • 和服务端进行通信(send/recv)
  • 关闭套接字

//基于TCP的服务端程序

#include <WinSock2.h>
#include <iostream>
#include <string>
#pragma comment(lib,"WS2_32") using std::cout;
using std::endl;
using std::string; //服务器端程序
void TcpServer()
{
//加载winsock库
WSADATA wsaData;
WORD socktVersion = MAKEWORD(2,2); //版本号
if (0 != ::WSAStartup(socktVersion,&wsaData)) //加载套接字库
{
return;
} //1、创建服务器端套接字
SOCKET serverSocket = ::socket(AF_INET,SOCK_STREAM,0); //使用TCP连接 //2、绑定套接字到指定IP和端口
sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(6000); //指定端口号
server_address.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //指定IP地址
::bind(serverSocket,(LPSOCKADDR)&server_address,sizeof(server_address)); //绑定IP地址与端口号 //3、设置套接字为监听状态
::listen(serverSocket,5);// char sendmsg[] = "TCP Server Say Hello!";
//4、等待客户端连接
cout << "\nWait For Connect...";
while (true)
{
SOCKET client_socket;
sockaddr_in client_address;
int address_len = sizeof(client_address);
client_socket = ::accept(serverSocket,(LPSOCKADDR)&client_address,&address_len); //等待连接
if (client_socket == INVALID_SOCKET)
{
cout << "\nFailed Accept!";
break;
}
char *str_adress = inet_ntoa(client_address.sin_addr);
cout << "\nA client connected. IP:" << str_adress; //5、收发数据
::send(client_socket,sendmsg,strlen(sendmsg),0); ::closesocket(client_socket);//关闭连接
} //6、关闭服务端socket
::closesocket(serverSocket);
::WSACleanup(); //释放winsock库
}

客户端程序:

#include <WinSock2.h>
#include <iostream>
#include <string> #pragma comment(lib,"WS2_32") using std::cout;
using std::endl;
using std::string; void TCPClient()
{
//加载winsock库
WSADATA wsaData;
WORD socktVersion = MAKEWORD(2,2); //版本号
if (0 != ::WSAStartup(socktVersion,&wsaData)) //加载套接字库
{
return;
} //1.建立socket
SOCKET clientSocket = ::socket(AF_INET,SOCK_STREAM,0); //使用TCP连接
//填写服务器地址
sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(6000); //连接端口号
server_address.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //服务器IP地址 //2、发出连接请求
if (-1 == ::connect(clientSocket,(LPSOCKADDR)&server_address,sizeof(server_address)))
{
cout << "\nConnect Server Failed!";
return;
} cout << "\nConnected to server...";
//3、收发数据
char rev_buf[1024] = {0};
::recv(clientSocket,rev_buf,1024,0);
cout << "\nReceive server msg: " << rev_buf;
//4、关闭连接
::closesocket(clientSocket);
::WSACleanup(); //释放winsock库
}

运行如下:

基于UDP(面向无连接)的socket编程

服务端程序流程如下:

  • 创建套接字(socket)
  • 绑定套接字到指定的IP和端口号(bind)
  • 等待接收数据(recvfrom)
  • 关闭套接字

客户端程序流程如下:

  • 创建套接字(socket)
  • 向服务端发送数据(sendto)
  • 关闭套接字

基于UDP的服务端程序,接收客户端发送的数据,并输出

void UdpServer()
{
//加载winsock库
WSADATA wsaData;
WORD socktVersion = MAKEWORD(2,2); //版本号
if (0 != ::WSAStartup(socktVersion,&wsaData)) //加载套接字库
{
return ;
} //1.建立socket
SOCKET serverSocket = ::socket(AF_INET,SOCK_DGRAM,0); //使用UDP协议
//填写地址
sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(6000); //连接端口号
server_address.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //服务器IP地址 //2、绑定套接字
::bind(serverSocket,(LPSOCKADDR)&server_address,sizeof(server_address)); //绑定IP地址与端口号 //3、接收数据
char recv_buf[1024] = {0};
sockaddr_in client_address;
int address_len = sizeof(client_address);
while (true)
{
//接收数据
int recv_cnt = ::recvfrom(serverSocket,recv_buf,1024,0,(sockaddr*)&client_address,&address_len);
if (recv_cnt > 0)
{
recv_buf[recv_cnt] = '\0';
cout << "\nReceive Data From " << inet_ntoa(client_address.sin_addr) << " : " << recv_buf;
}
}
//3、关闭连接
::closesocket(serverSocket);
::WSACleanup(); //释放winsock库
}

客户端程序:

void UdpClient()
{
//加载winsock库
WSADATA wsaData;
WORD socktVersion = MAKEWORD(2,2); //版本号
if (0 != ::WSAStartup(socktVersion,&wsaData)) //加载套接字库
{
return ;
} //1.建立socket
SOCKET clientSocket = ::socket(AF_INET,SOCK_DGRAM,0); //使用UDP协议
//填写服务器地址
sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(6000); //连接端口号
server_address.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //服务器IP地址 //2、收发数据
char send_buf[1024] = {0};
string input_str;
bool is_finished = false;
while (!is_finished)
{
cout << "Input Send Msg: ";
std::getline(std::cin,input_str);
if (input_str.empty())
{
continue;
}
if ("exit" == input_str)
{
is_finished = true;
continue;
}
sprintf_s(send_buf,1024,"%s",input_str.c_str());
::sendto(clientSocket,send_buf,strlen(send_buf),0,(sockaddr*)&server_address,sizeof(server_address)); //发送数据
}
//3、关闭连接
::closesocket(clientSocket);
::WSACleanup(); //释放winsock库
}

Winsock网络编程的更多相关文章

  1. Winsock网络编程笔记(1)----入门

    今天第一次接触winsock网络编程,看的资料是Windows网络编程第二版.通过博客记住自己的看书笔记.. 在这里贴出第一个程序,虽然程序什么都没做,但以此作为入门,熟悉其网络编程风格.. #inc ...

  2. WinSock网络编程基础(1)

    记录学习windows网络编程过程中遇到的问题和相关笔记 基本概念: Socket: socket起源于UNIX,Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.基于&qu ...

  3. WinSock网络编程基础(2)客户端

    接下来说一下如何用WinSock创建基于TCP/IP模型的客户端和服务器. TCP可以提供两个计算机间可靠无误的数据传输,应用程序使用TCP通信时,会在两台计算机之间建立一个虚拟连接,连接之后计算机之 ...

  4. Winsock网络编程笔记(4)----基本的理论知识

    前面的笔记记录了Winsock的入门编程,领略了Winsock编程的乐趣..但这并不能算是掌握了Winsock,加深理论知识的理解才会让后续学习更加得心应手..因此,这篇笔记将记录一些有关Winsoc ...

  5. Winsock网络编程笔记(3)----基于UDP的server和client

    在上一篇随笔中,对Winsock中基于tcp面向连接的Server和Client通信进行了说明,但是,Winsock中,Server和Client间还可以通过无连接通信,也就是采用UDP协议.. 因此 ...

  6. Winsock网络编程笔记(2)----基于TCP的server和client

    今天抽空看了一些简单的东西,主要是对服务器server和客户端client的简单实现. 面向连接的server和client,其工作流程如下图所示: 服务器和客户端将按照这个流程就行开发..(个人觉得 ...

  7. WinSock网络编程基础(3)server

    上一篇讲的是简单的发送数据的客户端的实现.接下来讲的是如何实现收发数据服务器.这里说的服务器其实就是一个进程,它需要等待任意数量的客户端与之建立起连接,以便响应它们的请求. 服务器必须在已知的名称上监 ...

  8. Winsock API编程介绍

    相信很多人都对网络编程感兴趣,下面我们就来介绍,在网络编程中应用最广泛的编程接口Winsock API. 使用Winsock API的编程,应该了解一些TCP/IP的基础知识.虽然你可以直接使用Win ...

  9. Windows平台VC++ 6.0 下的网络编程学习 - 简单的测试winsock.h头文件

    最近学习数据结构和算法学得有点累了(貌似也没那么累...)...找了本网络编程翻了翻当做打一个小基础吧,打算一边继续学习数据结构一边也看看网络编程相关的... 简单的第一次尝试,就大致梳理一下看书+自 ...

随机推荐

  1. word2010没有“标题2、标题3”样式的解决办法

    word2010没有“标题2.标题3”样式的解决办法 很多人用word的时候都喜欢用“标题1”“标题2”等样式来定义他们的文档标题,被这样定义的标题会出现在导航窗格中,使浏览起来非常方便.但是最近我发 ...

  2. window下node更新

    打开cmd查看你之前node版本安装的路径,where node: 直接去官网下载与你电脑系统(32位还是64位)对应的最新的mis版本,安装在上述路径中覆盖即可. 注意:windows上并不支持n模 ...

  3. centos 7安装jdk、tomcat

    jdk安装 创建上传目录: [root@ckl1 home]# pwd /home [root@ckl1 home]# mkdir upload 安装上传工具: yum install lrzsz 上 ...

  4. 使用eclipse执行maven-release-plugin插件发布jar异常问题(.project)(Cannot prepare the release because you have local modifications )

    开发是用的eclipse,里面有工程文件.project这种文件,运行release:prepare的时候报异常: Cannot prepare the release because you hav ...

  5. VC++ 多线程编程,win32,MFC 例子(转)

    一.问题的提出 编写一个耗时的单线程程序: 新建一个基于对话框的应用程序SingleThread,在主对话框IDD_SINGLETHREAD_DIALOG添加一个按钮,ID为IDC_SLEEP_SIX ...

  6. Making Promises With

    转:Making Promises With http://www.htmlgoodies.com/beyond/javascript/making-promises-with-jquery-defe ...

  7. MJExtension的一些实用技巧

    1.在代码文件中 引入"MJExtension.h" :解决属性中的命名和服务端传过来的数据中的key不同的问题 -(NSDcitionrary *)replacedkeyFrom ...

  8. 扩展Spring切面

    概述 Spring的切面(Spring动态代理)在Spring中应用十分广泛,例如还有事务管理,重试等等.网上介绍SpringAop源码很多,这里假设你对SpringAop有基本的了解.如果你认为Sp ...

  9. rs.getMetadata

    元数据(MetaData),即定义数据的数据.打个比方,就好像我们要想搜索一首歌(歌本身是数据),而我们可以通过歌名,作者,专辑等信息来搜索,那么这些歌名,作者,专辑等等就是这首歌的元数据.因此数据库 ...

  10. numpy.ndarray的赋值操作

    mat=zeros((3,4)) #生成一个3行4列全部元素为0的矩阵 mat[1,:]=111 #从第1行第0列开始,一直到最后一列,赋值为1,效果与mat[1,0:3]相同,前置0可以省略,最后的 ...