Winsock 示例
#include "stdafx.h"
#include <Windows.h>
#include <iostream> #pragma comment(lib,"ws2_32.lib") using namespace std; int main(int argc, char* argv[]){
WSADATA wsaData;
int err;
err=WSAStartup(MAKEWORD(,),&wsaData);//如果这里是(1,1)则下面第一个输出为257,即0x0101
if(err==){
cout<<"success"<<endl;
}
cout<<"Windows Sockets DLL期望调用者使用的Windows Sockets规范的版本: "<<wsaData.wVersion<<endl;//0x0202
cout<<"这个DLL能够支持的Windows Sockets规范的最高版本.通常它与wVersion相同: "<<wsaData.wHighVersion<<endl;//0x0202
//So, to initialise an application to support Winsock 1.1 you'd use a value of 257 ( 0000000100000001 binary). For Winsock 2.2 you'd use 514 ( 0000001000000010 binary).
system("pause");
return ;
}
网络编程框架:
写一个网络应用程序分为两个方面:服务器程序和客户端程序,大家可以在一个solution中建立srv和client两个projects。
首先回忆一下程序框架
#include<winsock2.h> // 头文件
#pragma comment(lib, "ws2_32.lib") // 库文件加载
void main(void)
{
WSADATA wsaData; // WSADATA 结构体主要包含了系统所支持的Winsock版本信息
// 初始化Winsock 2.2。使用WSAStartup函数,第一个参数是所要用的Winsock版本号
// 第二个参数就是WSADATA结构体的指针。如果初始化成功则返回0
// 要注意任何WinsockAPI函数都必须在初始化后使用,包括错误检查函数
// WSAGetLastError (用于查看出错详细信息)
if( WSAStartup( MAKEWORD(2,2), &wsaData) != 0 )
{
printf( "WSAStartup 无法初始化!");
return;
}
// winsock 应用代码
// 最后应该做一些清除工作
if( WSACleanup() == SOCKET_ERROR )
printf( "WSACleanup 出错!");
}
现在我们的任务是填写红色的部分,即winsock应用代码
1. 简单TCP/IP
思路:
[服务器程序]
建立socket -----> 绑定bind------>监听listen------>接受accept------>发送和接收send 和 recv------>关闭closesocket
[客户端程序]
建立socket -----> 连接connect------>发送和接收send 和 recv------>关闭closesocket
代码:
[服务器程序]
/*使用IP地址家族就必须要用AF_INET,由于我们要建立可靠的传送,因此我们选择SOCK_STREAM,基于数据流的传送,最后一个参数表示使用TCP协议,实际上这个参数可以设置为0,让程序自己根据情况判断填写*/
SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP )
/*绑定的意思是把socket绑定到IP地址上,所以我们需要一个SOCKADDR结构来存放IP地址信息,这里为了方便填写可以使用SOCKADDR_IN结构,这个结构的大小和SOCKADDR一样,可以强制类型转换到SOCKADDR类型,填写给bind函数的参数。这里要注意的是要把IP地址和端口号转化为网络存储顺序,即高位存放在低字节内存中,可以用htonl和htons函数转化*/
SOCKADDR_IN addrSrv;
addrSrv.sin_family = AF_INET;
addrSrv.sin_addr.s_addr = htonl( INADDR_ANY); // INADR_ANY表示使用默认IP地址
addrSrv.sin_port = htons( 27015 );//尽量不要使用在1024以下的端口
bind( sockSrv, (SOCKADDR*)&addrSrv, sizeof(addrSrv) );
/*监听,第二个参数表示等待序列的最大个数,就好比最多只能容纳5个人排队,第六个就被拒绝排队了。*/
listen( sockSrv, 5 );
/* 接受, 就好比处理房间中第一个人的事务,那么这个队列就空出一个人的位置,其他人还可以来排队。这里通过accept函数可以返回一个表示连接进来的客户的socket,并且通过传递参数可以知道客户端的IP地址信息*/
SOCKADDR_IN addrClient;
int len = sizeof(addrClient);
// 循环接受客户,这里没有写退出条件,实际上退出条件可以来自判断所读入的信息
while(1)
{
SOCKET sockClient = accept( sockSrv, (SOCKADDR*)&adrClient, &len );
// 发送和接收数据 char sendbuf[32] = "Server: Sending Data.";
char recvbuf[32] = "";
// recv 和 send的参数都是 socket,buffer,buffer的大小以及一个flag,具体可参考MSDN
bytesRecv = recv( sockClient, recvbuf, 32, 0 );
printf( "Recv: %s\n", recvbuf );
bytesSent = send( sockClient, sendbuf, strlen(sendbuf), 0 );
}
// 关闭socket
closesocket(sockClient);
closesocket(sockSrv);
完整代码:
#include "stdafx.h"
#include<winsock2.h>
#include<iostream>
#pragma comment(lib,"ws2_32.lib") using namespace std;
int main(){
WSADATA wsaData;
SOCKET s;
int errStartup,errBind;
errStartup=WSAStartup(MAKEWORD(,),&wsaData);
if(errStartup!=){
cout<<"初始化失败"<<endl;
return -;
}
if (LOBYTE(wsaData.wVersion)!=2||HIBYTE(wsaData.wVersion)!=2)
{
MessageBox(NULL,_T("error"),NULL,NULL);
WSACleanup();
return -4;
}
s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(s==INVALID_SOCKET){
cout<<"创建socket失败"<<endl;
WSACleanup();
return -;
}
SOCKADDR_IN addr;
memset(&addr,,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addr.sin_port=htons();
errBind= bind(s,(SOCKADDR*)&addr,sizeof(addr));
if(errBind!=){
cout<<"bind failed!"<<endl;
closesocket(s);
WSACleanup();
return -;
}
listen(s,); SOCKADDR_IN addrClient;
int len=sizeof(addrClient); while (true)
{
SOCKET sockClient=accept(s,(SOCKADDR*)&addrClient,&len);
char *sendBuf="Server:sending data.";
char recBuf[]={};
memset(recBuf,,sizeof(recBuf));
int sendNum= send(sockClient,sendBuf,strlen(sendBuf)+,);
cout<<sendNum<<endl;
int recNum= recv(sockClient,recBuf,,);
cout<<recBuf<<" from "<<inet_ntoa(addrClient.sin_addr)<<endl; shutdown(sockClient,SD_BOTH);
closesocket(sockClient);
} closesocket(s);
WSACleanup();
system("pause");
return ;
}
[客户端程序]
// client.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <WinSock2.h>
#include <iostream>
using namespace std; #pragma comment(lib,"ws2_32.lib") int _tmain(int argc, TCHAR *argv[])
{
WSADATA wsaData;
SOCKADDR_IN s;
int conerr;
WSAStartup(MAKEWORD(,),&wsaData); SOCKET clientSock=socket(AF_INET,SOCK_STREAM,);
memset(&s,,sizeof(s));
s.sin_family=AF_INET;
s.sin_addr.S_un.S_addr=inet_addr("172.18.4.161");
s.sin_port=htons();
conerr= connect(clientSock,(SOCKADDR*)&s,sizeof(s));
if(conerr!=){
cout<<"connect failed:"<<conerr<<endl; }
char *sendBuf="Client:sending data.";
char recBuf[]={};
memset(recBuf,,sizeof(recBuf)); int recNum= recv(clientSock,recBuf,,);
cout<<recBuf<<endl;
int sendNum= send(clientSock,sendBuf,strlen(sendBuf)+,);
cout<<sendNum<<endl; system("pause");
return ;
}
不同机器之间通信切记把防火墙关掉!!!从控制面板中关闭,不要直接关服务
2. 简单UDP/IP
思路:
[服务器程序]
建立socket -----> 绑定bind------>发送和接收sendto 和 recvfrom------>关闭closesocket
[客户端程序]
建立socket -----> 发送和接收send 和 recv------>关闭closesocket
UDP的实现更加简单,服务器只要绑定就可以发送接收信息,而客户端只要有socket就可以了。具体的实现代码可以参考MSDN中的例子。
要注意的是:
TCP中用SOCK_STREAM 建立socket,并且使用send和recv函数发送接收信息。
UDP中用SOCK_DGRAM 建立socket,并且使用sendto和recvfrom来发送和接收信息。sendto 比send多几个参数,主要是对方的IP地址信息,recvfrom也是一样比recv多几个参数。
Winsock 示例的更多相关文章
- 与众不同 windows phone (46) - 8.0 通信: Socket, 其它
[源码下载] 与众不同 windows phone (46) - 8.0 通信: Socket, 其它 作者:webabcd 介绍与众不同 windows phone 8.0 之 通信 Socket ...
- Winsock 入门 Echo 示例
#include <stdio.h> #include <winsock2.h> #pragma comment(lib, "ws2_32") /* Win ...
- Winsock select server 与 client 示例代码
参考 https://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancediomethod5.html ...
- Winsock 入门 计算校验和 示例
#include <stdio.h> #include <string.h> #define DATA_MAX_LEN 14 /* 最大数据长度 */ struct data_ ...
- Winsock 入门 判读主机字节序 示例
#include <stdio.h> union endian_u { /*最大成员的长度就是联合成员的长度.联合可以在定义时直接进行初始化,但这个初始化必须是联合第一个成员的类型,所以把 ...
- winsock教程- windows下的socket编程(c语言实现)
winsock教程- windows下的socket编程(c语言实现) 使用winsock进行socket 编程 这是一个学习windows下socket编程(c语言)的快速指南.这是因为一下 ...
- C# Windows Sockets (Winsock) 接口 (转)
在.Net中,System.Net.Sockets 命名空间为需要严密控制网络访问的开发人员提供了 Windows Sockets (Winsock) 接口的托管实现.System.Net 命名空间中 ...
- winsock编程IOCP模型实现代码
winsock编程IOCP模型实现代码 话不多说,上代码.借鉴<windows核心编程>部分源码和CSDN小猪部分代码. stdafx.h依赖头文件: #include <iostr ...
- 一步一步从原理跟我学邮件收取及发送 5.C语言的socket示例
说到 C 语言版本的程序,首先要解决的问题就是兼容性. 作为 20 年开发有 10 多年是在服务端的程序员,我深刻地感受到服务端平台的两极分化之严重,linux 派对 windows 那是超级的不屑一 ...
随机推荐
- IOS 发布被拒 PLA 1.2问题 整个过程介绍 02 个人账户升级公司账户
首先,根据上一篇文章得出结论: 1.个人账户,可以发布非营销的APP.例如:公司企业站.个人站 2.公司账户,可以发布营销的APP.例如:京东,天猫,带有盈利的APP 3.企业账户,是使用在公司内部的 ...
- Spring data jpa 实现简单动态查询的通用Specification方法
本篇前提: SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法 这篇文章中的第二种方法 实现Specification 这块的方法 只适用于一个对象针对某一个固定字 ...
- iOS中,Framework和.a的打包及使用
最近在做一个小项目,需要给客户一个demo测试,有一部分核心代码暂时不想让客户知道,就想到了打包成framework或.a库.库有两种: 静态库:.a和.framework 动态库:.tbd和.fra ...
- eclipse web项目导入itellij idea并启动
概述 主要分为项目配置和tomcat配置两大步骤. 一.项目配置 打开idea,选择导入项 选择将要打开的项目路径后,继续选择项目的原本类型(后续引导设置会根据原本的项目类型更新成idea的项目),此 ...
- 实现继承+接口继承+虚方法+隐藏方法+this/base+抽象类+密封类/方法+修饰符
概念: 在上一节课中学习了如何定义类,用类当做模板来声明我们的数据. 很多类中有相似的数据,比如在一个游戏中,有Boss类,小怪类Enemy,这些类他们有很多相同的属性,也有不同的,这个时候我们可以使 ...
- c++中函数参数传递(值传递、指针传递,引用传递)进一步认识
概念 首先从概念上来说一下这几种函数传参方式及区别: 1.值传递:形参是实参的拷贝,改变函数形参的值并不会影响外部实参的值,这是最常用的一种传参方法,也是最简单的一种传参方法,只需要传递参 ...
- 高性能Js-加载和执行
Js文件加载和执行 单线程 概念:浏览器使用单一线程处理UI渲染和js脚本执行(只触发一次) 问题:等待js文件下载.解析.执行,UI渲染和用户界面刷新被阻塞(异步方式解决) 关键:文件加载.文件执行 ...
- 《Advanced Bash-scripting Guide》学习(十九):两个整数的最大公约数
本文所选的例子来自于<Advanced Bash-scripting Gudie>一书,译者 杨春敏 黄毅 #!/bin/bash #求两个整数的最大公约数 E_BADARGS= #如果参 ...
- JDK所有版本
http://www.oracle.com/technetwork/java/archive-139210.html
- vue配置stylus
首先Vue-init webapck 随便一个name vue项目创建好之后 cnpm i (利用淘宝镜像) cnpm i stylus stylus-loader -D 进行安装和配置 styl常 ...