最简单的Tcp Udp的例子
//1.WinSock包含2个主要的版本,即WinSock1和WinSock2.前者需要包含头文件WinSock.h和库文件wsock32.lib,后者需要包含头文件WinSock2.h和库文件ws2_32.lib用于提供对网络相关API的支持。 //2.WSAData结构体的定义
typedef struct WSAData
{
WORD wVersion;
WORD wHighVersion;
#ifdef _WIN64
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
char szDescription[WSADESCRIPTION_LEN+];
char szSystemStatus[WSASYS_STATUS_LEN+];
#else
char szDescription[WSADESCRIPTION_LEN+];
char szSystemStatus[WSASYS_STATUS_LEN+];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
#endif
} WSADATA, FAR * LPWSADATA; //3.MAKEWORD():由两个字节生成一个WORD //typedef unsigned short WORD;
WORD MAKEWORD
(
BYTE bLow, //指定新变量的低字节序;
BYTE bHigh //指定新变量的高字节序;
);
WORD temValue = MAKEWORD(0x12, 0x34); //temValue = 0x3412 //4.WSAStartup():
// 返回0为成功
// WSAStartup应该与WSACleanup成对使用
// WSAStartup的功能是初始化Winsock DLL
// 本函数必须是应用程序或DLL调用的第一个Windows Sockets函数.
// 它允许应用程序或DLL指明Windows Sockets API的版本号及获得特定Windows Sockets实现的细节.
// 应用程序或DLL只能在一次成功的WSAStartup()调用之后才能调用进一步的Windows Sockets API函数. //5.WSACleanup():
// WSACleanup是来解除与Socket库的绑定并且释放Socket库所占用的系统资源。
// WSACleanup操作成功返回值为0;否则返回值为SOCKET_ERROR
// 在一个多线程的环境下,WSACleanup中止了Windows Sockets在所有线程上的操作.
// 对应于一个任务进行的每一次WSAStartup()调用,必须有一个WSACleanup()调用.只有最后的WSACleanup()做实际的清除工作;前面的调用仅仅将Windows Sockets DLL中的内置引用计数递减
//6.LOWORD()得到一个32bit数的低16bit
// HIWORD()得到一个32bit数的高16bit
// LOBYTE()得到一个16bit数最低(最右边)那个字节
// HIBYTE()得到一个16bit数最高(最左边)那个字节 //7.网络字节顺序:在低位存储地址中保存数据的高位字节,就是大端字节序。规定不同系统间通信一律采用网络字节序。
// 主机字节顺序:在本机存储时候的保存数据方式。在本机是低位存储地址中保存数据的低位。
// 在进程发送数据之前,都必须将数据转为网络字节顺序。
// 字节序是大端在前还是小端在前是取决于cpu的而不是取决于操作系统的,本机为小端模式 //8.typedef struct sockaddr_in SOCKADDR_IN;
struct sockaddr_in
{
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[];
};
typedef struct in_addr
{
union
{
struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { USHORT s_w1,s_w2; } S_un_w;
ULONG S_addr;
} S_un;
#define s_addr S_un.S_addr // can be used for most tcp & ip code
#define s_host S_un.S_un_b.s_b2 // host on imp
#define s_net S_un.S_un_b.s_b1 // network
#define s_imp S_un.S_un_w.s_w2 // imp
#define s_impno S_un.S_un_b.s_b4 // imp #
#define s_lh S_un.S_un_b.s_b3 // logical host
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;
// struct sockaddr是通用的套接字地址,而struct sockaddr_in则是internet环境下套接字的地址形式,二者长度一样,都是16个字节。
// 二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。一般情况下,需要把sockaddr_in结构强制转换成sockaddr结构再传入系统调用函数中。
typedef struct sockaddr
{
#if (_WIN32_WINNT < 0x0600)
u_short sa_family;
#else
ADDRESS_FAMILY sa_family; // Address family.
#endif //(_WIN32_WINNT < 0x0600) CHAR sa_data[]; // Up to 14 bytes of direct address.
} SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR; //9.inet_addr():将点分十进制的IP地址转为网络字节序的IP地址
unsigned long value = inet_addr("127.0.0.1"); //value = 0x0100007f
// inet_ntoa():将网络字节序的IP地址转为点分十进制的字符串
in_addr temValue;
temValue.S_un.S_addr = 0x0100007f;
char *str = inet_ntoa(temValue); //str = "127.0.0.1" //10.主机顺序与网络顺序格式之间的转换
// htonl()--"Host to Network Long"
// ntohl()--"Network to Host Long"
// htons()--"Host to Network Short"
// ntohs()--"Network to Host Short" //11.socket():用于创建与指定的服务绑定的套接字
// socket():第一个参数指明协议族,主要为:
// AF_INET:又称PF_INET,是IPv4网络协议的套接字类型
// AF_INET6:是IPv6的
// 第二个参数指明套接口类型:
// 为SOCK_STREAM:提供顺序,可靠,双向和面向连接的字节流数据传输机制,使用TCP
// SOCK_DGRAM:支持无连接的数据报,使用UDP
// SOCK_RAW:原始套接字,可以用于接收本机网卡上的数据
// 第三个参数一般为0
// 成功时,返回一个小的非负整数值,与文件描述符类似。失败返回INVALID_SOCKET
typedef UINT_PTR SOCKET;
typedef _W64 unsigned int UINT_PTR, *PUINT_PTR;
#define INVALID_SOCKET (SOCKET)(~0)
#define AF_INET 2 // internetwork: UDP, TCP, etc.
#define AF_INET6 23 // Internetwork Version 6 //12.bind:把一个本地协议地址赋予一个套接字
// 第一个参数是一个套接字
// 第二个参数是指向SOCKADDR指针
// 第三个参数是SOCKADDR结构体的长度
// 成功返回0,失败返回SOCKET_ERROR
#define SOCKET_ERROR (-1) //13.用listen():创建套接口并为申请进入的连接建立一个后备日志,然后便可用accept()接受连接了。
// listen()仅适用于支持连接的套接口,如SOCK_STREAM类型的。套接口处于一种“变动”模式,
// 申请进入的连接请求被确认,并排队等待被接受。这个函数特别适用于同时有多个连接请求的服务器;
// 如果当一个连接请求到来时,队列已满,那么客户将收到一个WSAECONNREFUSED错误。
// 如无错误发生,listen()返回0。否则的话,返回SOCKET_ERROR //14.accept():从已完成连接队列返回下一个已完成连接。如果已完成连接队列为空,那么调用线程将被投入睡眠(假定套接字设为阻塞方式)。
// 如果函数调用成功,则返回一个新建的SOCKET,用于实现服务器和客户端之间的通信,若调用失败,则返回INVALID_SOCKET。 //15.recv():从已连接的SOCKET中接受数据。其第四个参数一般为0。也可以是以下值:
#define MSG_OOB 0x1 // process out-of-band data 处理带宽外的数据
#define MSG_PEEK 0x2 // peek at incoming message 数据将赋值到缓冲区中,但是并不从输入队列中删除这些数据
// 调用成功,则返回接受数据的字节数。如果连接已经断开则返回0,否则返回SOCKET_ERROR. //16.send():可以向已连接的SOCKET上发送数据。其第四个参数一般为0。也可以是以下值:
#define MSG_OOB 0x1 // process out-of-band data 处理带宽外的数据
#define MSG_DONTROUTE 0x4 // send without using routing tables 指定数据不选择路由
// 调用成功则返回发送数据长度,可能小于其第三个参数指定的长度。如果出现错误返回SOCKET_ERROR。 //17.closesocket():用于关闭一个SOCKET,释放其所占用的资源。应该在WSACleanup()函数前调用。成功返回0,失败返回SOCKET_ERROR。 //18.shutdown():可以用于禁止在指定的SOCKET上接受和发送数据。当其第二个参数有如下选择
#define SD_RECEIVE 0x00 //禁止接受数据
#define SD_SEND 0x01 //禁止发送数据
#define SD_BOTH 0x02 //禁止接受和发送数据
// 成功返回0,失败返回SOCKET_ERROR //19.connect():connect()用于建立与指定SOCKET的连接
// connect在进行连接的时候会默认等待一会,如没有建立连接则返回失败。成功返回0,失败返回SOCKET_ERROR
1.TCP服务器
#include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData; if (WSAStartup(MAKEWORD(,), &wsaData) != )
{
return -;
}
if (LOBYTE(wsaData.wVersion) != || HIBYTE(wsaData.wVersion) != )
{
WSACleanup();
return -;
} SOCKET sockfd = socket(AF_INET, SOCK_STREAM, ); if (INVALID_SOCKET == sockfd)
{
WSACleanup();
return ;
} SOCKADDR_IN serAddr = {};
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons();
serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); if (SOCKET_ERROR == bind(sockfd, (SOCKADDR*)(&serAddr), sizeof(SOCKADDR)))
{
closesocket(sockfd);
WSACleanup();
return -;
} if (listen(sockfd, ) != )
{
closesocket(sockfd);
WSACleanup();
return -;
} SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR);
SOCKET clientSocket = accept(sockfd, (SOCKADDR*)&addrClient, &len); if (INVALID_SOCKET == clientSocket)
{
closesocket(sockfd);
WSACleanup();
return -;
} if (send(clientSocket, "", , ) <= )
{
closesocket(sockfd);
closesocket(clientSocket);
WSACleanup();
return -;
} char buff[] = {}; if (recv(clientSocket, buff, , ) <= )
{
closesocket(sockfd);
closesocket(clientSocket);
WSACleanup();
return -;
} printf("%s\n", buff);
system("pause"); closesocket(sockfd);
closesocket(clientSocket);
//注意点:所有打开的SOCKET都需要进行关闭 WSACleanup();
return ;
}
2.TCP客户端
#include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(, ), &wsaData) != )
{
return -;
} if (LOBYTE(wsaData.wVersion) != || HIBYTE(wsaData.wVersion) != )
{
WSACleanup();
return -;
} SOCKET sockClient = socket(AF_INET, SOCK_STREAM, );
if (INVALID_SOCKET == sockClient)
{
WSACleanup();
return -;
} SOCKADDR_IN sockAddr = {};
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons();
sockAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); if (SOCKET_ERROR == connect(sockClient, (SOCKADDR*)&sockAddr, sizeof SOCKADDR))
{
closesocket(sockClient);
WSACleanup();
return -;
} char buff[] = {};
if (recv(sockClient, buff, , ) <= )
{
closesocket(sockClient);
WSACleanup();
return -;
}
printf("%s\n", buff); if (send(sockClient, "", , ) <= )
{
closesocket(sockClient);
WSACleanup();
return -;
}
system("pause"); closesocket(sockClient);
WSACleanup();
return ;
}
3.Udp发送方
//1.sendto():
// 第一个参数:用于发送数据的套接字
// 第二个参数:发送缓冲区
// 第三个参数:发送长度
// 第四个参数:标志位。一般为0。可以为MSG_DONTROUTE和MSG_OOB。(效果在send()中使用一致)
// 第五个参数:指定数据接收方的地址
// 第六个参数:第五个参数的数据长度 #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(, ), &wsaData) != )
{
return -;
}
if (LOBYTE(wsaData.wVersion) != || HIBYTE(wsaData.wVersion) != )
{
WSACleanup();
return -;
} SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, );
if (INVALID_SOCKET == sockClient)
{
WSACleanup();
return -;
} SOCKADDR_IN sockAddr;
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons();
sockAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); int sendLength = sendto(sockClient, "", , , (SOCKADDR*)&sockAddr, sizeof SOCKADDR);
if (sendLength <= )
{
closesocket(sockClient);
WSACleanup();
return -;
} closesocket(sockClient);
WSACleanup();
return ;
}
4.Udp接收方
//1.recvfrom():
// 第一个参数:用于监听的套接字
// 第二个参数:接受缓冲区
// 第三个参数:接受长度
// 第四个参数:调用方式。一般为0。可以为MSG_PEEK,MSG_OOB。(效果和在recv()中使用一致)
// 第五个参数:用于保存发送方地址
// 第六个参数:第五个参数长度 #include "stdafx.h"
#include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(, ), &wsaData) != )
{
return -;
}
if (LOBYTE(wsaData.wVersion) != || HIBYTE(wsaData.wVersion) != )
{
WSACleanup();
return -;
} SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, );
if (INVALID_SOCKET == sockSrv)
{
WSACleanup();
return -;
} SOCKADDR_IN sockAddr;
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = htons();
sockAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); if (SOCKET_ERROR == bind(sockSrv, (SOCKADDR*)&sockAddr, sizeof SOCKADDR))
{
closesocket(sockSrv);
WSACleanup();
} char buff[] = {}; int len = sizeof SOCKADDR;
SOCKADDR_IN ClientAddr = {};
int recvLength = recvfrom(sockSrv, buff, , , (SOCKADDR*)&ClientAddr, &len); closesocket(sockSrv);
WSACleanup();
return ;
}
最简单的Tcp Udp的例子的更多相关文章
- [JSBSim]基于winsocket2的TCP\UDP使用例子
TCP部分: 参考:http://blog.csdn.net/sbfksmq/article/details/50808863 另附:linux下的tcp/udp参考:https://www.cnbl ...
- python tcp,udp简单使用
import socket host = '127.0.0.1' port = 9999 #创建一个tcp socket套接字 tcp_server = socket.socket(socket.AF ...
- 网络基础--简单理解什么是DNS? TCP? UDP? Http? Socket?
什么是IP 协议? 协议就是为了实现网络通信而创建的一系列规范. 通常我们的网络模型从上到下共分为4层: 应用层, 传输层, 网络层 和数据链路层. IP协议属于网络层协议,它精确定义了网络通信中 ...
- 为什么基于TCP UDP服务的一些简单服务端口号都是奇数
TCP是有NCP(网络控制协议)派生出来的,NCP是单工的,通信需要两个链接,所以会预留奇偶端口号.当TCP/UDP成为传输层协议,每个程序只是用一个端口号,且使用奇端口号.
- [转][linux]简单的linux下的tcp/udp
转自:https://blog.csdn.net/cabing2005/article/details/53068880 详细函数以及参数解释请看原链接. windows下的tcp/udp参考:htt ...
- TODO:Golang语言TCP/UDP协议重用地址端口
TODO:Golang语言TCP/UDP协议重用地址端口 这是一个简单的包来解决重用地址的问题. go net包(据我所知)不允许设置套接字选项. 这在尝试进行TCP NAT时尤其成问题,其需要在同一 ...
- [转]vb socket通信(TCP/UDP)一对一、多对一
VB Socket编程(Winsock控件创建TCP/IP客户机/服务器程序) Winsock控件建立在TCP.UDP协议的基础上,完成与远程计算机的通信.即使对TCP/IP不太熟悉的用户,使用 ...
- Java中的TCP/UDP网络通信编程
127.0.0.1是回路地址,用于测试,相当于localhost本机地址,没有网卡,不设DNS都可以访问. 端口地址在0~65535之间,其中0~1023之间的端口是用于一些知名的网络服务和应用,用户 ...
- Java TCP/UDP网络通信编程
本文转自:http://www.cnblogs.com/cdtarena/archive/2013/04/10/3012282.html 网络应用中基本上都是TCP(Transmission Cont ...
随机推荐
- P85练习3
public class P85Excise { public static void main(String[] args) { // TODO 自动生成的方法存根 int i =1; float ...
- Python实用工具包Scrapy安装教程
对于想用每个想用Python开发网络爬虫的开发者来说,Scrapy无疑是一个极好的开源工具.今天安装之后觉得Scrapy的安装确实不易啊.所以在此博文一篇,往后来着少走弯路. 废话不多说了,如果 ...
- WIN API 擦除所绘图像
COLORREF circle_color = RGB(0, 105, 255); //获取窗口DC HDC hdc = GetDC(hWnd_); //背景色透明 SetBkMode(hdc, TR ...
- CDH介绍
本文引用自:Cloudera 系列2:CDH介绍http://www.aboutyun.com/thread-18379-1-1.html(出处: about云开发) CDH提供: 灵活性-存储任何类 ...
- 读书笔记——《图解TCP/IP》(1/4)
读书笔记——<图解TCP/IP>(1/4) 经典摘抄 第一章 网络基础知识 1.独立模式:计算机未连接到网络,各自独立使用的方式. 2.广域网 WAN 局域网 LAN 城域网 MAN 3. ...
- HashSet HashTable HashMap的区别
(1)HashSet是set的一个实现类,hashMap是Map的一个实现类,同时hashMap是hashTable的替代品(为什么后面会讲到). (2)HashSet以对象作为元素,而HashMap ...
- 【C】用我所学去讲C语言指针
很多人不敢讲C的指针,有些人讲不清,有些人怕讲错.初生牛犊不怕虎,就让我讲讲. 下面开始. 一.指针的定义 指针是内存单元的编号.内存单元是以字节为单位的.所以指针就是字节的编号. 比如我们的个人电 ...
- 关于YARN的HA
一:准备 1.规划 namenode namenode ZKFC ZKFC journalnode journalnode jou ...
- 原因是未找到“sgen.exe”,或未安装 .NET Framework SDK v2.0
visual studio编译出现错误:错误 2 任务失败,原因是未找到“sgen.exe”,或未安装 .NET Framework SDK v2.0.该任务正在注册表项 HKEY_LOCAL_MAC ...
- 各个JSON技术的比较
JSON技术的调研报告 一 .各个JSON技术的简介和优劣1.json-libjson-lib最开始的也是应用最广泛的json解析工具,json-lib 不好的地方确实是依赖于很多第三方包,包括com ...