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 的执行环境是单线程的,所谓的单线程就是一次只能完成一个任务,其任务的调度方式就是排队,这就和火车站洗手间门口的等待一样,前面的那个人没有搞定,你就只能站在后面排队等着. ...
随机推荐
- [CSS布局]简单的CSS三列布局
前言 公司终于可以上外网了,近期在搞RN的东西,暂时脑子有点晕,等过段时间再来写点总结.倒是最近有个新学前端的同学经常会问一些基础知识,工作空闲写了小Demo给他看,全是很基础的知识,纯粹是顺便记录在 ...
- java 反转数组
package java03; public class Demo05ArrayReversr { public static void main(String[] args) { int[] arr ...
- 两个对象值相同(x.equals(y)==true),hashcode也相同
不对,如果两个对象x和y满足x.equals(y) == true,它们的哈希码(hash code)应当相同.Java对于eqauls方法和hashCode方法是这样规定的:(1)如果两个对象相同( ...
- HashMap、HashTable、ConcurrentHashMap区别
HashMap与HashTable区别 HashMap与ConcurrentHashMap区别 1.HashMap与HashTable的区别 HashMap线程不安全,HashTable线程安全 Ha ...
- Android Fastboot 与 Recovery 和刷机 千山万水迷了鹿
1. 首先来看下Android系统的分区: Android系统的分区.jpg Android分区解释.png 安卓系统一般把rom芯片分成7个区,如果再加上内置sd卡这个分区,就是8个: hb ...
- 【CF1238E】Keyboard Purchase(状压DP,贡献)
题意:有m种小写字符,给定一个长为n的序列,定义编辑距离为序列中相邻两个字母位置差的绝对值之和,其中字母位置是一个1到m的排列 安排一种方案,求编辑距离最小 n<=1e5,m<=20 思路 ...
- Sticks
题目链接 题意:给你一组等长木棒,然后他随意砍断成n个木棒,木棒长度不一,但你知道分别是多少,要你求出原始木棒可能的最小长度. 思路:首先那个原始木棒的长度肯定是其总长度的约数,然后也肯定大于等于所有 ...
- vue和php-前后台交互
vue和php-前后台交互 前端主要代码: <template> <div class="main-member-info"> <form @subm ...
- speike
speike 题目描述 众所周知,Speike 狗是一条特别喜欢追着Tom 打的狗. 现在,Tom 又把Speike 惹生气了,现在Speike 需要跨越千山万水找Tom 报仇. Speike 所在的 ...
- HDU4762 Cut the Cake
HDU4762 Cut the Cake 思路:公式:n/m(n-1) //package acm; import java.awt.Container; import java.awt.geom.A ...