网络通信常用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. codeforces472D

    Design Tutorial: Inverse the Problem CodeForces - 472D 给你了一个 n × n最短距离矩阵.(即矩阵中dis[u][v]为u点到v点的最短距离), ...

  2. Linux Ubuntu安装sogou中文输入法

    在linux下开发,有时还是需要使用中文输入法的,每次安装的时候都觉得痛苦,这次做下记录,方便下次安装. 安装fcitx 安装sogou输入法之前,需要安装fcitx(Free Chinese Inp ...

  3. HDU 3367 (伪森林,克鲁斯卡尔)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=3367 Pseudoforest Time Limit: 10000/5000 MS (Java/Oth ...

  4. DMA(Direct Memory Access)简介

    什么是DMA(Direct Memory Access) DMA绕过CPU,在内存和外设之间开辟了一条 "隧道" ,直接控制内存与外设之间的操作,并完全由硬件控制. 这样数据传送不 ...

  5. Linux环境下部署SpringBoot项目

    1.在pom文件中添加maven插件 <build> <plugins> <plugin> <groupid>org.springframework.b ...

  6. Java中的集合框架-Map

    前两篇<Java中的集合框架-Commection(一)>和<Java中的集合框架-Commection(二)>把集合框架中的Collection开发常用知识点作了一下记录,从 ...

  7. GPUImage源码解读之GLProgram

    简述 GLProgram是GPUImage中代表openGL ES 中的program,具有glprogram功能.其实是作者对OpenGL ES program的面向对象封装 初始化 - (id)i ...

  8. js基础(闭包实例)

    1,常用发送短信的闭包实现: function sms() { var count = 60; return { start: function() { if(count == 0) { count ...

  9. 安装ubuntu 18.04总结

    今天开发组的一个妹子同事想把系统换成ubuntu的,过来找我,给装完后,做个总结..... 以下开始操作 环境:小米air ,系统win10,cpu intel_m3 一)下载ubuntu 的镜像 h ...

  10. Django学习笔记6(iframe、外键插入)

    1.{%include 'index.html'%i} 平时很好用的iframe在django里面的不是很好用 django里面提供了{%include 'index.html'%i}的方式来取代了i ...