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 ...
随机推荐
- python 笔试总结
1.对比两种函数对应结果 def fn(x): if x>0: print(x) fn(x-1) ****结果****** 3 2 1 $$$$$$另外一种$$$$$$$$$ def fn(x) ...
- [错误处理]AttributeError: 'generator' object has no attribute 'next'
在python3下学习yield用法. 程序如下: def bar(n): m = n while True: m += 1 yield m b = bar(3) print(b.next()) 程序 ...
- jquery的html、text、val的用法
.html()用为读取和修改元素的HTML标签 .text()用来读取或修改元素的纯文本内容 .val()用来读取或修改表单元素的value值. 这三个方法功能上的对比 .html(),.text() ...
- PAT1023
给定数字0-9各若干个.你可以以任意顺序排列这些数字,但必须全部使用.目标是使得最后得到的数尽可能小(注意0不能做首位).例如:给定两个0,两个1,三个5,一个8,我们得到的最小的数就是1001555 ...
- 第二个python自动化练习
#Author:xiaoxiao from selenium import webdriver import unittest class DownLoad(unittest.TestCase): # ...
- 截图神器-snipaste
基础操作 Snipaste 是一个简单但强大的贴图工具,同时也可以执行截屏.标注等功能. 截屏 开始截图 快捷键(默认为 F1) 鼠标左键 单击托盘图标 何谓一次 成功的截图 保存到剪贴板 ( / ...
- Java实现简单的socket通信
今天学习了一下java如何实现socket通信,感觉难点反而是在io上,因为java对socket封装已经很完善了. 今天代码花了整个晚上调试,主要原因是io的flush问题和命令行下如何运行具有pa ...
- BZOJ 4460 [Jsoi2013]广告计划 ——Bitset 后缀自动机
发现n比较小,直接枚举答案,然后发现连续的一段是确定的,然后我们只需要判断每个位置是否有这个连续的一段就好了 发现起点不同,最后的位置可能会有差距,所以DP一下就好了 然后用0表示未折返,1表示从最下 ...
- service中显示一个dialog
dialog是依附于activity存在的.但是app中经常需要使用以下的情况,在service中做一些后台操作,在某个临界条件满足时,显示一个dialog告知用户.这时dialog无法直接从serv ...
- Java面试题之在多线程情况下,单例模式中懒汉和饿汉会有什么问题呢?
懒汉模式和饿汉模式: public class Demo { //private static Single single = new Single();//饿汉模式 private static S ...