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 的执行环境是单线程的,所谓的单线程就是一次只能完成一个任务,其任务的调度方式就是排队,这就和火车站洗手间门口的等待一样,前面的那个人没有搞定,你就只能站在后面排队等着. ...
随机推荐
- 使用eclipse创建Spring Boot项目
环境介绍 1.jdk1.8 2.eclipse 3.maven 3.5.0 创建项目 eclectic 左上角 file -> new -> maven project 出现下图默认就好, ...
- [NOIP2017普及组]跳房子(二分,单调队列优化dp)
[NOIP2017普及组]跳房子 题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则如下: 在地面上确定一个起点,然后在起点右侧画 nn 个格子, ...
- Android】Retrofit网络请求参数注解,@Path、@Query、@QueryMap...(转)
对Retrofit已经使用了一点时间了,是时候归纳一下各种网络请求的service了. 下面分为GET.POST.DELETE还有PUT的请求,说明@Path.@Query.@QueryMap.@Bo ...
- shell 单行多行注释
1. 单行注释 众所周知,# 比如想要注释:echo “ni” # echo "ni" 2. 多行注释: 法一: : << ! 语句1 语句2 语句3 语句4 ! 法 ...
- Center os6.5设置静态ip
DEVICE="eth0"BOOTPROTO=staticHWADDR="00:0C:29:95:89:35"IPV6INIT="yes"N ...
- javascript 设置cookie和取得cookie
代吗实例: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- 前端每日实战:72# 视频演示如何用纯 CSS 创作气泡填色的按钮特效
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/eKqZjy 可交互视频 此视频是可 ...
- shiro 安全框架 详解
---恢复内容开始--- Shiro 简介 简介• Apache Shiro 是 Java 的一个安全(权限)框架.• Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE 环境, ...
- boost IOStreams
Boost.IOStreams provides numerous implementations of the two concepts. Devices which describes data ...
- boost graph
Boost Graph provides tools to work with graphs. Graphas are two-dimensional point clouds with any nu ...