windows 网络编程[转]
利用winsock编写网络应用程序服务端的步骤简述如下
WSAStartup 初始化网络编程库
socket 创建套接字
bind 指定地址、端口,绑定套接字
listen 进入监听状态
accept 等待接收新连接
send/recv 收发数据
closesocket 关键套接字
WSAStartup 释放对动态库的使用
下面详细介绍各API
1. Winsock初始化
调用int WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData )函数
WSAStartup,即WSA(Windows SocKNDs Asynchronous,Windows异步套接字)的启动命令。是Windows下的网络编程接口软件Winsock1 或 Winsock2 里面的一个命令(Ps:Winsock 是由Unix下的BSD Socket发展而来,是一个与网络协议无关的编程接口)。
为了在应用程序当中调用任何一个Winsock API函数,首先第一件事情就是必须通过WSAStartup函数完成对Winsock服务的初始化,因此需要调用WSAStartup函数。使用Socket的程序在使用Socket之前必须调用WSAStartup函数。
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested=MAKEWORD(2,2);
if(WSAStartup(wVersionRequested,&wsaData)!=0)
{
//初始化失败
}
if(wsaData.wVersion != wVersionRequested)
{
//版本不匹配
}
2. 创建套接字
int socket(int domain, int type, int protocol);
函数说明:
第一个参数指定应用程序使用的通信协议的协议族,对于TCP/IP协议族,该参数置AF_INET;
第二个参数指定要创建的套接字类型,流套接字类型为SOCK_STREAM、数据报套接字类型为SOCK_DGRAM、原始套接字SOCK_RAW(WinSock接口并不适用某种特定的协议去封装它,而是由程序自行处理数据包以及协议首部);
第三个参数指定应用程序所使用的通信协议。此参数可以指定单个协议系列中的不同传输协议。在Internet通讯域中,此参数一般取值为0,系统会根据套接字的类型决定应使用的传输层协议。
返回值:成功返回套接字描述符,否则返回INVALID_SOCKET。
例子:
if ((m_sk = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
//创建套接字失败
}
3. 绑定套接字
地址结构的定义:
/*
* Socket address, internet style.
*/
struct sockaddr_in {
short sin_family; //协议族
u_short sin_port; //端口号
struct in_addr sin_addr; //地址信息
char sin_zero[8];
};
/*
* Internet address (old style... should be updated)
*/
struct in_addr {
union {
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { u_short s_w1,s_w2; } S_un_w;
u_long S_addr;
} S_un;
#define s_addr S_un.S_addr
/* can be used for most tcp & ip code */
/*
* Structure used by kernel to store most
* addresses.
*/
struct sockaddr {
u_short sa_family; /* address family */
char sa_data[14]; /* up to 14 bytes of direct address */
};
注意:s_addr是一个宏,可以方便设置地址
#define s_addr S_un.S_addr
/* can be used for most tcp & ip code */
/*
* Structure used by kernel to store most
* addresses.
*/
struct sockaddr {
u_short sa_family; /* address family */
char sa_data[14]; /* up to 14 bytes of direct address */
};
注意:s_addr是一个宏,可以方便设置地址
上述定义在winsock2.h中
绑定函数原型:
int bind( int sockfd , const struct sockaddr * my_addr, socklen_t addrlen);
函数说明:
参数列表中,sockfd 表示已经建立的socket编号(描述符);
my_addr 是一个指向sockaddr结构体类型的指针;
参数addrlen表示my_addr结构的长度,可以用sizeof函数获得。
例子:
sockaddr_in addr;
addr.sin_family = AF_INET; //使用互联网际协议,即IP协议
addr.sin_port = htons(port);
addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
IP地址参数为INADDR_ANY,则由系统内核来自动指定
port为0,则由系统自动指派一个1024~5000之间惟一的端口号
if (bind(m_sk, (sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR)
{
//绑定出错
}
4. 进入监听状态
int listen(int s, int backlog);
函数说明:
s:已绑定的套接字
backlog:同时能处理的最大连接数
Listen()并未开始接收连线, 只是设置socket 为listen 模式, 真正接收client 端连线的是accept(). 通常listen()会在socket(), bind()之后调用, 接着才调用accept()。
5. 接受连接
int accept(int s,struct sockaddr * addr,int * addrlen);
当有新的连接到来时,accept返回一个新的套接字描述符。连接请求端的相关信息存储在addr中。
参数sockfd
参数sockfd是监听套接字,这个套接字用来监听一个端口,当有一个客户与服务器连接时,它使用这个端口号,而此时这个端口号正与这个套接字关联。当然客户不知道套接字这些细节,它只知道一个地址和一个端口号。
参数addr
这是一个结果参数,它用来接受一个返回值,这返回值指定客户端的地址,当然这个地址是通过某个地址结构来描述的,用户应该知道这一个什么样的地址结构。如果对客户的地址不感兴趣,那么可以把这个值设置为NULL。
参数len
也是结果的参数,用来接受上述addr的结构的大小的,它指明addr结构所占有的字节个数。同样的,它也可以被设置为NULL。
如果accept成功返回,则服务器与客户已经正确建立连接了,此时服务器通过accept返回的套接字来完成与客户的通信
6. 收发数据
int send(int s, const void *buf, int len, int flags);
int recv(int s, void *buf, int len, int flags);
函数返回实际收发的字节数。出错返回-1, 需要关闭此连接。
函数缺省是阻塞函数,直到发送/接收完成。
注意:如果send 函数返回值与参数len 不相等,则剩余的未发送信息需要再次发送
recv接收到数据之后不会在末尾添加’\0’。
7. 其它API
WSAGetLastError()
获取上次失败操作的错误状态
closesocket(int socket)
关闭套接字
WSACleanup()
终止Winsock 2 DLL (Ws2_32.dll) 的使用
windows 网络编程[转]的更多相关文章
- [转]Windows网络编程学习-面向连接的编程方式
直接附上原文链接:windows 网络编程学习-面向连接的编程方式
- Windows网络编程 2 【转】
Windows网络编程使用winsock.Winsock是一个基于Socket模型的API,在Windows系统中广泛使用.使用Winsock进行网络编程需要包含头文件Winsock2.h,需要使用库 ...
- Windows 网络编程
网络编程 API ,失败返回 -,错误代码 WSASYSNOTREADY 表示基础网络子系统没有准备好网络通行,WSAVERNOTSUPPORTED 表示 Socket 版本不支持,WSAEINPRO ...
- windows网络编程的一些理论
参考自<VC++深入详解> 这是我在看书时记录下来的东西. 注:下面的Socket其实都应该是socket 第14章网络编程 Socket是连接应用程序与网络驱动程序的桥梁,Socket在 ...
- Windows网络编程(C/C++服务器编程)
Windows服务器网络编程 Linux服务器网络编程
- Windows网络编程笔记4 -- Winsock 协议相关知识
Win32平台上的Winsock编程,Winsock是一个与协议无关的接口.以下协议是我们需要了解的: 网络协议的特征包括: 1. 面向消息 2. 面向连接和无线接 3. 可靠性和次序性 4. ...
- Windows网络编程笔记1
第一部分 传统网络API 传统的网络接口NetBIOS.重定向器.邮槽.命名管道等.第一,NetBIOS(Network Basic Input/Output System, NetBIOS)“网络基 ...
- windows网络编程-2015.12.29
在windows环境下,使用netstat命令查看网络状态,具体命令如下所示: netstat -ano | findstr listenport 在windows环境下,创建udp程序接收端,具体代 ...
- Windows网络编程笔记6 --- WinSock I/O 控制方法
Windows提供了两种方式“套接字模式”和“套接字I/O模型”,可对一个套接字上的I/O行为加以控制.套接字模式用于决定在随一个套接字调用时,那些 Winsock函数的行为.其中的模型包括括sele ...
随机推荐
- 聊聊、Java 命令 第三篇
这篇随笔主要写启动 jar 时,如果需要依赖其他的 jar 包该怎么处理,我会以 rabbitMQ 客服端启动为例. package com.rockcode.www.rabbitmq; import ...
- [oldboy-django][1初始django]模态对话框 + 动态加载gif (多对多数据库表)
ajax+对话框(多对多) - 遮罩层,动态加载gif层,对话框层, a.一点击添加,绑定事件: - 出现遮罩层和动态gif层 - ajax向后台发送请求获取所有班级数据 - success,隐藏动态 ...
- [问题解决]docker启动不了
问题描述:昨天下午整合了同事的代码,发现docker启动好后,docker ps查看不到,docker ps -a发现docker容器没有启动. 尝试多次启动发现都是启动不了. 经过搜索发现 http ...
- PAT1028
某城镇进行人口普查,得到了全体居民的生日.现请你写个程序,找出镇上最年长和最年轻的人. 这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过200岁的老人,而今天是2014年9月 ...
- POJ 2983:Is the Information Reliable?(差分约束)
题目大意:有n个点在一条直线上,有两类关系:P(x,y,v)表示x在y北边v距离处,V(x,y)表示x在y北边至少1距离出,给出一些这样的关系,判断是否有矛盾. 分析: 差分约束模板题,约束条件P:a ...
- BZOJ2806 [Ctsc2012]Cheat 【后缀自动机 + 二分 + 单调队列优化DP】
题目 输入格式 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库 的行数 接下来M行的01串,表示标准作文库 接下来N行的01串,表示N篇作文 输出格式 N行,每行一个整数,表示这篇作文的 ...
- ionic2如何调用百度地图
使用ionic2接入百度地图 在index.html中引入百度地图的js类库 <script type="text/javascript" src="http:// ...
- HDU [P3849]
tarjan 求 无向图的割边 (桥) 边 (x,y) 是桥当且仅当, 对于 x 的子节点 y ,low[x] < dfn[y] 对于连向父节点的边要特殊处理 #include <iost ...
- C# WebHTTPUtil工具类
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- 时间戳/Date(1354116249000)/ 转换
从C#的Datatime格式通过Json传到Js里面,时间会显示成时间戳/Date(1354116249000)/ ,js转化如下 function GetDateFormat(str) { retu ...