Winsock编程原理——面向连接
Winsock编程原理——面向连接
Windows Sockets使用套接字进行编程,套接字编程是面向客户端/服务器模型而设计的,因此系统中需要客户端和服务器两个不同类型的进程,根据连接类型的不同,对于面向连接的TCP服务和无连接的UDP服务,服务器分别采取不同的处理操作来对客户提供服务。
面向连接
/*
服务器端代码
*/ #include<Winsock2.h>
#include<stdio.h>
#include<stdlib.h>
#pragma comment(lib,"ws2_32.lib")
#define PORT 5000 void main()
{
int port = PORT; //端口
WSADATA wsaData; //存储系统传回的关于Winsock的资料
SOCKET sListen, sAccept; //套接字
int iLen; //客户地址长度
int iSend; //发送数据长度
char buf[] = "Hello, How are you!"; //需要发送的信息
struct sockaddr_in serv, cliet; //服务器、客户的地址 if (WSAStartup(MAKEWORD(, ), &wsaData) != ) //函数WSAStartup用以打开Winsock
{
printf("Winsock load failed\n");
return;
} sListen = socket(AF_INET, SOCK_STREAM, ); //创建套接字,TCP协议
if (sListen == INVALID_SOCKET) //socket调用成功返回套接字对象,失败返回INVALID_SOCKET
{
printf("socket failed:%d\n", WSAGetLastError());
return;
} serv.sin_family = AF_INET; //网络中标识不同设备使用的地址类型,对于IP地址,类型是AF_INET
serv.sin_port = htons(port); //socket对应的端口号
serv.sin_addr.s_addr = htonl(INADDR_ANY); //封装了IP地址
if (bind(sListen, (LPSOCKADDR)&serv, sizeof(serv)) == SOCKET_ERROR) //绑定套接字
{
printf("bind() failed:%d\n", WSAGetLastError());
return;
} if (listen(sListen, ) == SOCKET_ERROR) //监听
{
printf("listen() failed:%d\n", WSAGetLastError());
return;
} iLen = sizeof(cliet); //初始化客户地址长度 while () //进入循环,等待客户连接请求
{
sAccept = accept(sListen, (struct sockaddr*)&cliet, &iLen); //客户端的套接字
if (sAccept == INVALID_SOCKET) //接受连接请求失败
{
printf("accept() failed:%d\n", WSAGetLastError());
break;
}
//输出客户端IP、端口
printf("accept() client IP:[%s], port:[%d]\n", inet_ntoa(cliet.sin_addr), ntohs(cliet.sin_port)); //给连接的客户发送消息
iSend = send(sAccept, buf, sizeof(buf), );
if (iSend == SOCKET_ERROR)
{
printf("send() failed:%d\n", WSAGetLastError());
break;
}
else if (iSend == )
break;
else
printf("send() byte:%d\n", send); closesocket(sListen); //关闭套接字
closesocket(sAccept); //关闭套接字
WSACleanup(); //关闭Winsock
}
while ();
}
server
/*
客户端程序
*/
#include<WinSock2.h>
#include<stdio.h>
#pragma comment(lib,"ws2_32.lib")
#define PORT 5000
#define BUFFER 1024 void main(int argc,char *argv[])
{
WSADATA wsaData;
SOCKET client;
int port = PORT;
int iLen; //从服务器接收的数据长度
char buf[BUFFER]; //接收数据的缓冲
struct sockaddr_in serv; //服务器端地址
memset(buf, , sizeof(buf)); //接受数据缓冲区初始化 if (WSAStartup(MAKEWORD(, ), &wsaData) != ) //函数WSAStartup用以打开Winsock
{
printf("Winsock load failed\n");
return;
} serv.sin_family = AF_INET; //需要连接服务器地址信息,AF_INET表示IP协议
serv.sin_port = htons(port); //端口
// serv.sin_addr.s_addr = inet_addr(argv[1]); //IP地址,转为二进制表示的字节IP地址,argv表示cmd下输入的参数
serv.sin_addr.s_addr = inet_addr("10.100.211.224");
client = socket(AF_INET, SOCK_STREAM, ); //客户端套接字,流套接字表示使用TCP协议
if (client == INVALID_SOCKET) //创建套接字失败
{
printf("socket() failed:%d\n", WSAGetLastError());
return;
} //连接服务器
if (connect(client, (struct sockaddr*)&serv, sizeof(serv)) == INVALID_SOCKET)
{
printf("connet() failed:%d\n", WSAGetLastError);
return;
}
else
{
iLen = recv(client, buf, sizeof(buf), ); //从服务器接收数据
if (iLen = )
return;
else if (iLen == SOCKET_ERROR)
{
printf("recv() failed:%d\n", WSAGetLastError());
return;
}
printf("recv() data from server:%s\n", buf);
} closesocket(client); //关闭套接字
WSACleanup; //关闭Winsock // system("pause"); //程序暂停
printf("press any key to continue"); //让程序等待
while ();
}
client
加入多线程机制,一个服务器,多个客户端
/*
服务器端代码
*/ #include<Winsock2.h>
#include <windows.h>
#include<stdio.h>
#include<stdlib.h>
#pragma comment(lib,"ws2_32.lib")
#define PORT 5000
class MySocket
{
private:
SOCKET accept;
struct sockaddr_in clientAddr;
public:
MySocket(SOCKET a, struct sockaddr_in c)
{
accept = a;
clientAddr = c;
}
void setAccept(SOCKET a)
{
accept = a;
}
void setClientAddr(struct sockaddr_in c)
{
clientAddr = c;
}
SOCKET getAccept()
{
return accept;
}
struct sockaddr_in getClientAddr()
{
return clientAddr;
}
};
DWORD WINAPI ThreadFuc(LPVOID lparam)
{
MySocket* mSocket = (MySocket*)lparam; //接收主线程传来的参数
char buf[] = "Hello, How are you!"; //需要发送的信息
int iSend = ;
//输出客户端IP、端口
printf("accept() client IP:[%s], port:[%d]\n", inet_ntoa(mSocket->getClientAddr().sin_addr), ntohs(mSocket->getClientAddr().sin_port));
//给连接的客户发送消息
iSend = send(mSocket->getAccept(), buf, sizeof(buf), );
if (iSend == SOCKET_ERROR)
{
printf("send() failed:%d\n", WSAGetLastError());
}
else if (iSend == )
printf("send() failed,no message send successfully\n");
else
printf("send() byte:%d\n", send);
closesocket(mSocket->getAccept()); //关闭套接字
return ;
} void main()
{
int port = PORT; //端口
WSADATA wsaData; //存储系统传回的关于Winsock的资料
SOCKET sListen, sAccept; //套接字
int iLen; //客户地址长度
struct sockaddr_in serv, cliet; //服务器、客户的地址 if (WSAStartup(MAKEWORD(, ), &wsaData) != ) //函数WSAStartup用以打开Winsock
{
printf("Winsock load failed\n");
return;
} sListen = socket(AF_INET, SOCK_STREAM, ); //创建套接字,TCP协议
if (sListen == INVALID_SOCKET) //socket调用成功返回套接字对象,失败返回INVALID_SOCKET
{
printf("socket failed:%d\n", WSAGetLastError());
return;
} serv.sin_family = AF_INET; //网络中标识不同设备使用的地址类型,对于IP地址,类型是AF_INET
serv.sin_port = htons(port); //socket对应的端口号
serv.sin_addr.s_addr = htonl(INADDR_ANY); //封装了IP地址
if (bind(sListen, (LPSOCKADDR)&serv, sizeof(serv)) == SOCKET_ERROR) //绑定套接字
{
printf("bind() failed:%d\n", WSAGetLastError());
return;
} if (listen(sListen, ) == SOCKET_ERROR) //监听
{
printf("listen() failed:%d\n", WSAGetLastError());
return;
} iLen = sizeof(cliet); //初始化客户地址长度 while () //进入循环,等待客户连接请求
{
sAccept = accept(sListen, (struct sockaddr*)&cliet, &iLen); //客户端的套接字
if (sAccept == INVALID_SOCKET) //接受连接请求失败
{
printf("accept() failed:%d\n", WSAGetLastError());
break;
}
else
{
MySocket* mSocket = new MySocket(sAccept, cliet);
HANDLE thread = CreateThread(NULL, NULL, ThreadFuc, mSocket, NULL, NULL);
// closesocket(sAccept);不能关闭,关闭则不行。
}
}
closesocket(sListen); //关闭套接字
WSACleanup(); //关闭Winsock
while ();
}
server
/*
客户端程序
*/
#include<WinSock2.h>
#include<stdio.h>
#pragma comment(lib,"ws2_32.lib")
#define PORT 5000
#define BUFFER 1024 void main(int argc, char *argv[])
{
WSADATA wsaData;
SOCKET client;
int port = PORT;
int iLen; //从服务器接收的数据长度
char buf[BUFFER]; //接收数据的缓冲
struct sockaddr_in serv; //服务器端地址
memset(buf, , sizeof(buf)); //接受数据缓冲区初始化 if (WSAStartup(MAKEWORD(, ), &wsaData) != ) //函数WSAStartup用以打开Winsock
{
printf("Winsock load failed\n");
return;
} serv.sin_family = AF_INET; //需要连接服务器地址信息,AF_INET表示IP协议
serv.sin_port = htons(port); //端口
// serv.sin_addr.s_addr = inet_addr(argv[1]); //IP地址,转为二进制表示的字节IP地址,argv表示cmd下输入的参数
serv.sin_addr.s_addr = inet_addr("192.168.0.21");
client = socket(AF_INET, SOCK_STREAM, ); //客户端套接字,流套接字表示使用TCP协议
if (client == INVALID_SOCKET) //创建套接字失败
{
printf("socket() failed:%d\n", WSAGetLastError());
return;
} //连接服务器
if (connect(client, (struct sockaddr*)&serv, sizeof(serv)) == INVALID_SOCKET)
{
printf("connet() failed:%d\n", WSAGetLastError);
return;
}
else
{
iLen = recv(client, buf, sizeof(buf), ); //从服务器接收数据
if (iLen = )
return;
else if (iLen == SOCKET_ERROR)
{
printf("recv() failed:%d\n", WSAGetLastError());
return;
}
printf("recv() data from server:%s\n", buf);
} closesocket(client); //关闭套接字
WSACleanup; //关闭Winsock // system("pause"); //程序暂停
printf("press any key to continue"); //让程序等待
while ();
}
client


Winsock编程原理——面向连接的更多相关文章
- socket编程原理
socket编程原理 1.问题的引入 1) 普通的I/O操作过程: UNIX系统的I/O命令集,是从Maltics和早期系统中的命令演变出来的,其模式为打开一读/写一关闭(open-write-rea ...
- 第1章 网络编程基础(2)——Socket编程原理
Socket编程原理 Socket是网络通信端点的一种抽象,它提供了一种发送和接收数据的机制. 流socket(SOCK_STREAM):双向.有序.无重复.并且无记录边界 数据报Socket(SOC ...
- Winsock编程基础介绍 .
相信很多人都对网络编程感兴趣,下面我们就来介绍,在网络编程中应用最广泛的编程接口Winsock API. 使用Winsock API的编程,应该了解一些TCP/IP的基础知识.虽然你可以直接使用Win ...
- 【VS开发】socket编程原理
socket编程原理 1.问题的引入 1) 普通的I/O操作过程: UNIX系统的I/O命令集,是从Maltics和早期系统中的命令演变出来的,其模式为打开一读/写一关闭(open-write-rea ...
- NetBIOS与Winsock编程接口
最近在看网络编程方面的书,由于不是通信专业出身的,以前理解的网络体系感觉就是tcp/ip,最近工作上接触到了一些光环网等乱七八糟的东西,有些基本的LC.SC连接器都不认识.花时间看了下计算机网络体系结 ...
- Winsock 编程流程
近期看了<Window程序设计>感觉在网络方面讲的不错,讲的非常通俗易懂.与大家一同交流 转载请注明出处:http://blog.csdn.net/u010484477谢谢^_^ 使用 W ...
- Delphi下的WinSock编程
一.定址 要通过Winsock建立通信,必须了解如何利用指定的协议为工作站定址.Winsock 2引入了几个新的.与协议无关的函数,它们可和任何一个地址家族一起使用:但是大多数情况下,各 ...
- Winsock 编程详解
转载请注明出处!本文地址:https://www.cnblogs.com/teternity/p/WinSock.html Winsock 编程 目录 通用函数讲解 WSAStartup WSACle ...
- JavaScript异步编程原理
众所周知,JavaScript 的执行环境是单线程的,所谓的单线程就是一次只能完成一个任务,其任务的调度方式就是排队,这就和火车站洗手间门口的等待一样,前面的那个人没有搞定,你就只能站在后面排队等着. ...
随机推荐
- Java疯狂讲义笔记——Lambda表达式
Java8新增的Lambda表达式 [特性]支持将代码块作为方法参数,Lambda表达式允许使用更简洁的代码来创建只有一个抽象方法的接口(这种接口被称为函数式接口)的实例. [组成部分]1,形参列表 ...
- 一、Spring Boot系列:通过Maven创建第一个项目
1.打开idea选择创建工程 2.创建maven工程,同时选择jdk1.8 注意:不需要勾选其他选项 3.填写项目名称 4.创建好maven项目后,在pom.xml文件中导入Spring Boot需要 ...
- Vue:列表渲染 v-for on a <template>
类似于 v-if,你也可以利用带有 v-for 的 <template> 渲染多个元素.比如: <html> <head> <title>Vue v-f ...
- windows平台搭建Mongo数据库复制集(类似集群)(一)
Replica Sets(复制集)是在mongodDB1.6版本开始新增的功能,它可以实现故障自动切换和自动修复功能成员节点的功能,各个DB之间的数据完全一致,大大降低了单点故障的风险. [] 以上 ...
- 05.配置为开发模式、配置静态资源locations、自定义消息转化器、FastJson
配置为开发模式,代码做了修改,不用重新运行 idea需要该配置,mac测试无效 <dependency> <groupId>org.springframework</gr ...
- Maven开始
1:加入Maven插件: 这句话的意思是: 从本地仓库找到相应的jar包 <localRepository>F:\RepMaven</localRepository 2:创建一个Ma ...
- 常见HTTP错误代码
了解更多HTTP错误代码 一些常见的状态码为: 200 - 服务器成功返回网页404 - 请求的网页不存在503 - 服务不可用详细分解: 1xx(临时响应)表示临时响应并需要请求者继续执行操作的状态 ...
- 【Vue】新版vue解决跨域问题
vue.config.js module.exports = { devServer: { proxy: { "/api": { target: "http://192. ...
- 高精度模板 洛谷Luogu P1932 A+B & A-B & A*B & A/B Problem
P1932 A+B & A-B & A*B & A/B Problem 题目背景 这个题目很新颖吧!!! 题目描述 求A.B的和差积商余! 输入输出格式 输入格式: 两个数两行 ...
- 文字在线中间,CSS巧妙实现分隔线的几种方法
单个标签实现分隔线: .demo_line_01{ padding: 0 20px 0; margin: 20px 0; line-height: 1px; border-left: 200px so ...