Winsock 示例


#include "stdafx.h"
#include <Windows.h>
#include <iostream>

#pragma comment(lib,"ws2_32.lib")

using namespace std;

int main(int argc, char* argv[]){
WSADATA wsaData;
int err;
err=WSAStartup(MAKEWORD(2,2),&wsaData);//如果这里是(1,1)则下面第一个输出为257,即0x0101
if(err==0){
cout<<"success"<<endl;
}
 cout<<"Windows Sockets DLL期望调用者使用的Windows Sockets规范的版本: "<<wsaData.wVersion<<endl;//0x0202 
   cout<<"这个DLL能够支持的Windows Sockets规范的最高版本.通常它与wVersion相同: "<<wsaData.wHighVersion<<endl;//0x0202 

    //So, to initialise an application to support Winsock 1.1 you‘d use a value of 257 ( 0000000100000001 binary).  For Winsock 2.2 you‘d use 514 ( 0000001000000010 binary).
system("pause");
return 0;
}

 网络编程框架:

写一个网络应用程序分为两个方面:服务器程序和客户端程序,大家可以在一个solution中建立srv和client两个projects。
 
首先回忆一下程序框架
 
#include<winsock2.h> // 头文件 
#pragma comment(lib, "ws2_32.lib") // 库文件加载 
void main(void) 

WSADATA wsaData; // WSADATA 结构体主要包含了系统所支持的Winsock版本信息 
 
// 初始化Winsock 2.2。使用WSAStartup函数,第一个参数是所要用的Winsock版本号 
// 第二个参数就是WSADATA结构体的指针。如果初始化成功则返回0 
// 要注意任何WinsockAPI函数都必须在初始化后使用,包括错误检查函数 
// WSAGetLastError (用于查看出错详细信息) 
 
if( WSAStartup( MAKEWORD(2,2), &wsaData) != 0 ) 

printf( "WSAStartup 无法初始化!"); 
return; 

 
// winsock 应用代码 
 
// 最后应该做一些清除工作 
if( WSACleanup() == SOCKET_ERROR ) 
printf( "WSACleanup 出错!"); 
 
}
现在我们的任务是填写红色的部分,即winsock应用代码
 
1. 简单TCP/IP
 
思路: 
[服务器程序]
 
建立socket -----> 绑定bind------>监听listen------>接受accept------>发送和接收send 和 recv------>关闭closesocket
 
[客户端程序]

 
建立socket -----> 连接connect------>发送和接收send 和 recv------>关闭closesocket
 
代码:
 
[服务器程序]
 
/*使用IP地址家族就必须要用AF_INET,由于我们要建立可靠的传送,因此我们选择SOCK_STREAM,基于数据流的传送,最后一个参数表示使用TCP协议,实际上这个参数可以设置为0,让程序自己根据情况判断填写*/

SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP ) 
 
/*绑定的意思是把socket绑定到IP地址上,所以我们需要一个SOCKADDR结构来存放IP地址信息,这里为了方便填写可以使用SOCKADDR_IN结构,这个结构的大小和SOCKADDR一样,可以强制类型转换到SOCKADDR类型,填写给bind函数的参数。这里要注意的是要把IP地址和端口号转化为网络存储顺序,即高位存放在低字节内存中,可以用htonl和htons函数转化*/

SOCKADDR_IN addrSrv;
addrSrv.sin_family = AF_INET;
addrSrv.sin_addr.s_addr = htonl( INADDR_ANY); // INADR_ANY表示使用默认IP地址 
addrSrv.sin_port = htons( 27015 );//尽量不要使用在1024以下的端口 
 
bind( sockSrv, (SOCKADDR*)&addrSrv, sizeof(addrSrv) );
 
/*监听,第二个参数表示等待序列的最大个数,就好比最多只能容纳5个人排队,第六个就被拒绝排队了。*/
listen( sockSrv, 5 );
 
/* 接受, 就好比处理房间中第一个人的事务,那么这个队列就空出一个人的位置,其他人还可以来排队。这里通过accept函数可以返回一个表示连接进来的客户的socket,并且通过传递参数可以知道客户端的IP地址信息*/
 
SOCKADDR_IN addrClient;
int len = sizeof(addrClient);
 
// 循环接受客户,这里没有写退出条件,实际上退出条件可以来自判断所读入的信息 
while(1)
{
SOCKET sockClient = accept( sockSrv, (SOCKADDR*)&adrClient, &len );
 
// 发送和接收数据 char sendbuf[32] = "Server: Sending Data.";
char recvbuf[32] = "";
 
// recv 和 send的参数都是 socket,buffer,buffer的大小以及一个flag,具体可参考MSDN 
bytesRecv = recv( sockClient, recvbuf, 32, 0 ); 
printf( "Recv: %s\n", recvbuf );
 
bytesSent = send( sockClient, sendbuf, strlen(sendbuf), 0 );
 
}
 
// 关闭socket 
closesocket(sockClient);
closesocket(sockSrv);
 
[客户端程序]
 
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP ) 
 
SOCKADDR_IN addrSrv;
addrSrv.sin_family = AF_INET;
addrSrv.sin_addr.s_addr = htonl( INADDR_ANY); // INADR_ANY表示使用默认IP地址 
addrSrv.sin_port = htons( 27015 );//尽量不要使用在1024以下的端口 
 
// 连接 
connect( sockSrv, (SOCKADDR*)&addrSrv, sizeof(addrSrv) );
 
// 发送和接收数据 
char sendbuf[32] = "Client: Sending Data.";
char recvbuf[32] = "";
 
// recv 和 send的参数都是 socket,buffer,buffer的大小以及一个flag,具体可参考MSDN 
bytesRecv = recv( sockClient, recvbuf, 32, 0 ); 
printf( "Recv: %s\n", recv);
 
bytesSent = send( sockClient, sendbuf, strlen(sendbuf), 0 );
 
 
// 关闭socket 
closesocket(sockClient);
 
 
 
2. 简单UDP/IP
 
思路: 
 
[服务器程序]
 
建立socket -----> 绑定bind------>发送和接收sendto 和 recvfrom------>关闭closesocket
 
[客户端程序]
 
建立socket -----> 发送和接收send 和 recv------>关闭closesocket
 
UDP的实现更加简单,服务器只要绑定就可以发送接收信息,而客户端只要有socket就可以了。具体的实现代码可以参考MSDN中的例子。

要注意的是:
TCP中用SOCK_STREAM 建立socket,并且使用send和recv函数发送接收信息。
UDP中用SOCK_DGRAM 建立socket,并且使用sendto和recvfrom来发送和接收信息。sendto 比send多几个参数,主要是对方的IP地址信息,recvfrom也是一样比recv多几个参数。

时间: 2024-08-11 03:24:54

Winsock 示例的相关文章

Winsock 入门 Echo 示例

1 #include <stdio.h> 2 #include <winsock2.h> 3 4 #pragma comment(lib, "ws2_32") /* WinSock 使用的库函数 */ 5 6 #define ECHO_DEF_PORT 7 /* 侦听的缺省端口 */ 7 #define ECHO_BUF_SIZE 256 /* 缓冲区的大小 */ 8 9 int main(int argc, char **argv) 10 { 11 WSADA

Winsock 入门 计算校验和 示例

1 #include <stdio.h> 2 #include <string.h> 3 4 #define DATA_MAX_LEN 14 /* 最大数据长度 */ 5 6 struct data_sum 7 { 8 char data[DATA_MAX_LEN]; /* 数据 */ 9 unsigned short checksum; /* 校验和 */ 10 }; 11 12 unsigned short ip_checksum(unsigned short *buf, in

Winsock 入门 判读主机字节序 示例

1 #include <stdio.h> 2 3 union endian_u 4 { 5 /*最大成员的长度就是联合成员的长度.联合可以在定义时直接进行初始化,但这个初始化必须是联合第一个成员的类型,所以把unsigned short sval放在第一个成员的原因*/ 6 unsigned short sval; 7 unsigned char cval[2]; 8 }; 9 10 int main(int argc, char *argv[]) 11 { 12 char *info = &

IOCP扩展方法AcceptEx, DisconnectEx, GetAcceptExSockaddr用法示例

这篇文章记录了我刚接触IOCP模型时的理解,对于初学者,应该算不错的调试程序,仅有一个400多行代码的dpr文件,可以直接用WriteLn输出信息,前提是会用delphi建立Console Application,当然你也可以很容易的就改成了C控制台程序或是其它语言.附加代码中有详细的注释,如果你已有IOCP经验,那么请不用在此浪费时间,这个示例不适合你.示例仅展示了IOCP中AcceptEx, DisconnectEx, GetAcceptExSockaddr等的用法.在文章最后有推荐的两个连

Windows Socket编程示例-TCP示例程序

前面一部分是介绍,后面有示例 1.网络中进程之间如何通信? 首要解决的问题是如何唯一标识一个进程,否则通信无从谈起!在本地可以通过进程PID来唯一标识一个进程,但是在网络中这是行不通的.其实TCP/IP协议族已经帮我们解决了这个问题,网络层的"ip地址"可以唯一标识网络中的主机,而传输层的"协议+端口"可以唯一标识主机中的应用程序(进程).这样利用三元组(ip地址,协议,端口)就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互. 使用TCP

Winsock基础编程

Winsock基础编程 Socket的英文原义是"孔"或"插座".作为BSD UNIX的进程通信机制,取后一种意思.通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.在Internet上的主机一般运行了多个服务软件,同时提供几种服务.每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务.Socket正如其英文原意那样,像一个多孔插座.一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏

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

winsock教程- windows下的socket编程(c语言实现) 使用winsock进行socket 编程 这是一个学习windows下socket编程(c语言)的快速指南.这是因为一下代码片段只能运行在windows下.windows API中的socket编程部分叫做winsock. 你电脑上做出的任何网络通信背后基本上都有socket,它是一个网络的基本组成部分.举个例子说当你在浏览器键入www.google.com的时候,socket连接到google.com并且取回那个页面然后才

delphi ICS控件示例解读

1 {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 3 Author: Fran鏾is PIETTE 4 Object: Demo program to show how to use TWSocket object is a very 5 simple server program. This server just wait for a client to 6 connect, th

C语言 Socket入门示例2——模拟远程CMD(客户端向服务器发送命令,服务端执行该命令)

只要把上一篇文章"C语言 Socket入门示例1"中的两段程序彻底搞懂,那么再看本文就没有任何难度了,因为仅仅是对上篇文章中服务端代码的简单修改扩充.但是简单修改过后,功能变得异常强大,犹如一个远程CMD.随着不断深入学习,功能将会变得越来越强大.欢迎大家评论指点. 1.服务端(Server): #include <stdio.h> #include <winsock2.h> #pragma comment(lib,"ws2_32.lib")