网络通信常用API

1. WSAStartup用于初始化WinSock环境

int WSAStartup(
WORD wVersionRequested,
LPWSADATA lpWSAData
);

wVersionRequested:当前进程能够使用Windows Socket的最高版本,目前指定2.2即可。

lpWSAData:指向一个WSAData结构体,接受Socket详细信息。

成功返回0

2. socket建立一个指定类型的SOCKET用于通信

SOCKET WSAAPI socket(
int af,
int type,
int protocol
);

af:address family,指定用于通信的网络地址类型,可以取值AF_INET(IPv4),AF_INET6(IPv6),AF_BTH(蓝牙)等。

type:指定传输类型,可以取值SOCK_STREAM(用于TCP),SOCK_DGRAM(用于UDP)等。

protocol:通信协议,可以取值IPPROTO_TCP,IPPROTO_UDP等。

成功返回一个可以用于通信的SOCKET,否则返回INVALID_SOCKET。

3. bind将socket和网络地址和端口绑定起来

int bind(
SOCKET s,
const struct sockaddr *name,
int namelen
);

s:一个未绑定的socket。

name:指向一个sockaddr对象,用于指定绑定的ip和端口信息。

namelen:sockaddr的长度,为什么这里还需要指定长度呢,因为name是根据socket的类型来指定不同的结构体的,可能是sockaddr_in(IPv4)或者sockaddr_in6(IPv6)。

成功返回0

4. listen将SOCKET设为监听状态,可以被客户端连接

int listen(
SOCKET s,
int backlog
);

s:一个未被连接的socket

backlog:可以连接的客户端的最大数目,如果指定为SOMAXCONN,则设置为最大的连接数量。

成功返回0

5. send通过指定socket发送数据

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

s:一个已经连接的socket。

buf:待发送数据

len:待发送数据的长度

flags:发送的一个标志设定,一般设为0

成功返回已发送的字节数目。这个数目可能小于len的。失败返回SOCKET_ERROR。

6. recv通过指定的socket接受数据

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

s:一个已经连接的socket

buf:接收数据的缓存区

len:缓存区长度

flags:接受数据的一个标志,一般设为0。

成功返回已接受数据的长度,失败返回SOCKET_ERROR,如果已经断开连接,返回0

7. shutdown关闭一个SOCKET的send或者recv功能

int shutdown(
SOCKET s,
int how
);

s:socket

how:指定该socket的某个功能不需要再使用,可以取值SD_RECEIVE(接收功能),SD_SEND(发送功能),SD_BOTH(发送和接收功能)。

成功返回0,失败返回SOCKET_ERROR

8. connect连接到服务端,服务端开启listen后,客户端就可以使用connect进行连接

int connect(
SOCKET s,
const struct sockaddr *name,
int namelen
);

s:一个未连接的socket

name,namelen:和bind中name,namelen参数一样

成功返回0,失败返回SOCKET_ERROR

9. closesocket关闭一个已经存在的socket

int closesocket(
SOCKET s
);

s:一个待关闭的socket。

成功返回0,失败返回SOCKET_ERROR

10. accept接收一个来自客户端的连接

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

s:一个已经listen的socket

addr:用于储存接收到的客户端的sockaddr信息

addrlen:连接的客户端的sockaddr长度。

socket通信示例

服务端和客户端测试代码

// NetWork1.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <stdio.h>
#include <tchar.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT 12345 //启动客户端
int startClient()
{
SOCKET ConnectSocket = INVALID_SOCKET;
struct sockaddr_in clientService;
char *sendbuf = "[Client]:客户端测试文本";
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN; // 创建一个TCP套接字
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket创建失败: %ld\n", WSAGetLastError());
WSACleanup();
return ;
} // 指定连接端口和ip信息
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
clientService.sin_port = htons(DEFAULT_PORT); // 连接服务端
iResult = connect(ConnectSocket, (SOCKADDR*)&clientService, sizeof(clientService));
if (iResult == SOCKET_ERROR) {
printf("连接失败: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return ;
} if (ConnectSocket == INVALID_SOCKET) {
printf("无法连接到指定服务端!\n");
WSACleanup();
return ;
} // 发送一段数据
iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), );
if (iResult == SOCKET_ERROR) {
printf("发送数据失败: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return ;
} printf("已发送数据大小: %ld\n", iResult); // 关闭发送功能,但是仍然可以接收
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("关闭发送功能失败: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return ;
} // 接收数据
do { iResult = recv(ConnectSocket, recvbuf, recvbuflen, );
if (iResult > )
printf("已接收: %d\n", iResult);
else if (iResult == )
printf("连接关闭\n");
else
printf("接收数据失败: %d\n", WSAGetLastError()); } while (iResult > ); //关闭套接字
closesocket(ConnectSocket);
WSACleanup();
return ;
} int startServer()
{
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
sockaddr_in service;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
char *sendbuf = "[Server]:服务端测试文本"; // 创建TCP套接字
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
printf("socket创建失败: %ld\n", WSAGetLastError());
WSACleanup();
return ;
}
// 设定绑定的ip和端口信息
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr("127.0.0.1");
service.sin_port = htons(DEFAULT_PORT); // 绑定套接字
iResult = bind(ListenSocket, (SOCKADDR *)&service, sizeof(service));
if (iResult == SOCKET_ERROR) {
printf("套接字绑定失败:%d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return ;
} iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("套接字监听失败: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return ;
} // 接受来自客户端的连接
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return ;
} // 关闭服务端套接字,表示不需要再接收新的客户端连接了,但是已经连接的套接字还是能通信
closesocket(ListenSocket); do {
//接收来自客户端的消息
iResult = recv(ClientSocket, recvbuf, recvbuflen, );
if (iResult > ) {
printf("已接收数据大小: %d\n", iResult); // 发送数据到客户端,这里就是将数据
iSendResult = send(ClientSocket, sendbuf, (int)strlen(sendbuf), );
if (iSendResult == SOCKET_ERROR) {
printf("发送失败: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return ;
}
printf("发送字节大小: %d\n", iSendResult);
}
else if (iResult == )
printf("连接已关闭\n");
else {
printf("接收数据失败: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return ;
}
} while (iResult > ); //关闭套接字以及清理套接字环境
closesocket(ClientSocket);
WSACleanup(); return ;
}
int main(int argc, char *argv[])
{
int iResult;
WSADATA wsaData;
//初始化套接字环境
iResult = WSAStartup(MAKEWORD(, ), &wsaData);
if (iResult != ) {
printf("初始化socket环境失败: %d\n", iResult);
return ;
}
if (argc == && strcmp(argv[], "c") == )
{
//客户端
return startClient();
}
else if (argc == && strcmp(argv[], "s") == )
{
//服务端
return startServer();
}
return ;
}

运行结果

后记

以上只是一个简单的socket通信示例,所有api调用都是阻塞的,非阻塞调用将在下文写出。

代码下载

Windows网络通信(一):socket同步编程的更多相关文章

  1. windows下的socket网络编程

    windows下的socket网络编程 windows下的socket网络编程 clinet.c 客户端 server.c 服务器端 UDP通信的实现 代码如下 已经很久没有在windows下编程了, ...

  2. windows下的socket网络编程(入门级)

    windows下的socket网络编程 clinet.c 客户端 server.c 服务器端 UDP通信的实现 代码如下 已经很久没有在windows下编程了,这次因为需要做一个跨平台的网络程序,就先 ...

  3. Cfree clion windows c语言 socket 网络编程

    server.c #include <stdio.h> #include <winsock2.h> #define SERVER_PORT 5208 //侦听端口 int ma ...

  4. Windows网络通信(二):socket异步编程

    简述 这里使用的API和同步编程的API是差不多的,只多了一个ioctlsocket和select函数.这里面涉及一个很重要的结构体fd_set.这里用到的API大部分都是windows和linux通 ...

  5. winsock教程- windows下的socket编程(c语言实现)

    winsock教程- windows下的socket编程(c语言实现) 使用winsock进行socket 编程     这是一个学习windows下socket编程(c语言)的快速指南.这是因为一下 ...

  6. windows socket网络编程基础知识

    下面介绍网络7层协议在WINDOWS的实现: 7层协议 WIN系统 ________________________________________ 7 应用层 7 应用程序 ____________ ...

  7. windows socket 网络编程

    样例代码就在我的博客中,包含六个UDP和TCP发送接受的cpp文件,一个基于MFC的局域网聊天小工具project,和此小工具的全部执行时库.资源和执行程序.代码的压缩包位置是http://www.b ...

  8. C#网络编程系列(两)它Socket同步TCPserver

    声明原文 笔者:竹zz  本文地址http://blog.csdn.net/zhujunxxxxx/article/details/44258719 转载请注明出处 文章系列文件夹 C#网络编程系列文 ...

  9. 基于C++简单Windows API的socket编程(阻塞模式)

    1. 概述:简单的基于Windows API的socket点对点聊天程序,为了方便初学者,本文代码均采用阻塞原理编写. 2. 代码样例 Server.cpp(服务端) #include <cst ...

随机推荐

  1. virtualbox+vagrant学习-4-Vagrantfile-3-Minimum Vagrant Version

    Minimum Vagrant Version 可以在Vagrantfile中指定一组vagrant版本需求,以强制人们使用带有Vagrantfile文件的vagrant特定版本.这可以帮助解决使用带 ...

  2. jquery 中 attr 和 prop 的区别

    问题:在jQuery引入prop方法后,什么时候使用attr,什么时候使用prop,两者区别. 判断: 对于HTML元素本身所有的固有属性,在处理的时候,使用prop方法 对于HTML元素后来我们自己 ...

  3. ThinkPhp表单令牌和字段映射

    开启表单令牌: 先在配置文件目录下定义tags.php 在里面添加 return array( 'view_filter' =>array('Behavior\TokenBuildBehavio ...

  4. 失败 - 模块“MonitorLoop”打开电源失败。

    启动虚拟机提示以下错误 失败 - 模块“MonitorLoop”打开电源失败. 磁盘空间满了

  5. 404 Note Found队-Alpha2

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:丹丹 组员7:家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示组内 ...

  6. Reading SBAR SDN flow-Based monitoring and Application Recognition

    概要 在sdn下,控制平面基于网络测量的的数据控制网络,而细粒度的管理得益于细粒度的测量数据.针对sdn环境下的细粒度测量(识别具体应用程序),可以实现对细粒度的流量管控. 设计了识别系统SBAR,对 ...

  7. linux的虚拟文件系统VFS

    虚拟文件系统(virtual file system),别名虚拟文件系统开关,是linux中的一个软件层,向用户空间提供文件系统操作接口. VFS包含的系统调用包括open(2).stat(2).re ...

  8. quartz定时任务时间表达式说明

    quartz定时任务时间表达式说明   这些星号由左到右按顺序代表 :    *    *     *     *    *     *   *     格式: [秒] [分] [小时] [日] [月 ...

  9. iview中tree的事件运用

    iview中的事件和方法如下: 案例说明: html代码 <Tree :data="data4" @on-check-change="choiceAll" ...

  10. tp5上传压缩包到相应文件并自动解压到相应文件下

    <?phpnamespace app\admin\controller\upload; use app\common\controller\Backend;use think\db;use th ...