VC++ socket编程实例
2015-08-25 10:21
381 查看
1. 两天计算机通信需要协议,通信的两台计算机IP必须唯一
2. 同一个计算机可以进行多个应用程序与其他计算机通信,IP地址唯一,而端口号是区别同一计算机(同一IP)的唯一标示。
3. 实际上就类似于一个办公室的总机号码(IP)和分机号码(端口号)
4. 协议:为了进行网络中的数据交换(通信)而建立的规则、标准或约定
5. 协议=语义+语法+规则
6. 不同层具有各自不同的协议
7. 上层使用下层提供的服务,实际通信在最底层完成
8. 对等层实体之间虚拟通信|
9. TCP:面向连接的可靠的传输协议
10. UDP:面向无连接的不可靠的传输协议
11. 端口是一种抽象的软件结构。应用程序通过系统调用与某端口建立连接后,传输层传给端口的数据都被响应的进行所接收,相应进程发给传输层的数据都通过该端口输出。
12. 端口用一个整数型标示符来表示。端口号跟协议相关,TCP/IP传输层的两个协议TCP和UDP是完全独立的两个软件模块,因此各自的端口号也相互独立。
13. 端口使用一个16位的数字来表示,它的范围是0~65535,1024以下的端口号保留给预定义的服务。例如:http使用的是80端口。
14. socket(套接字):windows sockets只支持一个通信区域:网际域(AF_INET),这个域被使用网际协议簇通信的进程使用。
15. C/S模式:客户机向服务器提出请求,服务器接收到请求后,提供相应的服务。
16. 套接字的类型
a)流式套接字:(SOCK_STREAM):面向连接可靠的数据传输服务,按顺序接收
b)数据包式套接字:(SOCK_DGRAM):无连接服务。接收顺序混乱。
c) 原始套接字(SOCK_RAM)
17. 基于TCP(面向连接)的socket编程
a)服务器端程序:
i. 创建套接字socket
ii. 将套接字绑定到一个本地地址和端口上bind
iii. 将套接字设为监听模式,准备接收客户请求listen
iv. 等待客户请求到了;当请求到来后,接收连接请求,返回一个新的对应于此次连接的套接字accept
v. 用返回的套接字和客户端进行通信rend/recv
vi. 返回,等待另一客户请求
vii. 关闭套接字
b)客户端程序:
i. 创建套接字socket
ii. 向服务端发出连接请求connect
iii. 和服务器端进行通信rend/recv
iv. 关闭套接字
18. 基于UDP的socket编程
a)服务器端(接收端)程序:
i. 创建套接字socket
ii. 将套接字绑定到一个本地地址和端口上bind
iii. 等待接收数据recv/from
iv. 关闭套接字
b)客户端(发送端)程序:
i. 创建套接字socket
ii. 向服务器发送数据sendto
iii. 关闭套接字
struct sockaddr {
u_short sa_family;
char sa_data[14];
};
c) 监听
d) 接受连接
22. 服务器端:
a)Socket
b)连接:connect
c) 接收:recv
d) 发送:send
e) 关闭:closesocket
23. Tcp服务端程序:
[cpp] view
plaincopy
#include <WINSOCK2.H>
#include <stdio.h>
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
listen(sockSrv,5);
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
while(1)
{
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
char sendBuf[100];
sprintf(sendBuf,"Welcome %s to 刘洼村",inet_ntoa(addrClient.sin_addr));
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
char recvBuf[100];
recv(sockConn,recvBuf,100,0);
printf("%s\n",recvBuf);
closesocket(sockConn);
}
}
24. Tcp客户端程序:
[cpp] view
plaincopy
#include <WINSOCK2.H>
#include <stdio.h>
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");//服务器端的地址
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
char recvBuf[100];
recv(sockClient,recvBuf,100,0);
printf("%s\n",recvBuf);
send(sockClient,"This is 刘洼村",strlen("This is 刘洼村")+1,0);
closesocket(sockClient);
WSACleanup();
}
25. 运行之后,开启了6个客户端,一个服务器端。程序运行效果:
26. 面向UDP的连接
27. 服务器:socket
a)bind
b)接收数据:
c) 关闭closesocket
d) Cleanup
28. UDP服务器端程序:
[cpp] view
plaincopy
#include <WINSOCK2.H>
#include <stdio.h>
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}
SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
char recvBuf[100];
recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
printf("%s\n",recvBuf);
closesocket(sockSrv);
WSACleanup();
}
28. UDP客户端:
a)socket定义
b)发送:
29. UDP客户端程序
[cpp] view
plaincopy
#include <WINSOCK2.H>
#include <stdio.h>
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}
SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
sendto(sockClient,"Hello 刘洼村",strlen("Hello 刘洼村")+1,0,
(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
closesocket(sockClient);
WSACleanup();
}
运行结果:
30. 注意:每个程序都要加上ws2_32.lib链接库。如下添加:
By 刘洼村
2. 同一个计算机可以进行多个应用程序与其他计算机通信,IP地址唯一,而端口号是区别同一计算机(同一IP)的唯一标示。
3. 实际上就类似于一个办公室的总机号码(IP)和分机号码(端口号)
4. 协议:为了进行网络中的数据交换(通信)而建立的规则、标准或约定
5. 协议=语义+语法+规则
6. 不同层具有各自不同的协议
7. 上层使用下层提供的服务,实际通信在最底层完成
8. 对等层实体之间虚拟通信|
9. TCP:面向连接的可靠的传输协议
10. UDP:面向无连接的不可靠的传输协议
11. 端口是一种抽象的软件结构。应用程序通过系统调用与某端口建立连接后,传输层传给端口的数据都被响应的进行所接收,相应进程发给传输层的数据都通过该端口输出。
12. 端口用一个整数型标示符来表示。端口号跟协议相关,TCP/IP传输层的两个协议TCP和UDP是完全独立的两个软件模块,因此各自的端口号也相互独立。
13. 端口使用一个16位的数字来表示,它的范围是0~65535,1024以下的端口号保留给预定义的服务。例如:http使用的是80端口。
14. socket(套接字):windows sockets只支持一个通信区域:网际域(AF_INET),这个域被使用网际协议簇通信的进程使用。
15. C/S模式:客户机向服务器提出请求,服务器接收到请求后,提供相应的服务。
16. 套接字的类型
a)流式套接字:(SOCK_STREAM):面向连接可靠的数据传输服务,按顺序接收
b)数据包式套接字:(SOCK_DGRAM):无连接服务。接收顺序混乱。
c) 原始套接字(SOCK_RAM)
17. 基于TCP(面向连接)的socket编程
a)服务器端程序:
i. 创建套接字socket
ii. 将套接字绑定到一个本地地址和端口上bind
iii. 将套接字设为监听模式,准备接收客户请求listen
iv. 等待客户请求到了;当请求到来后,接收连接请求,返回一个新的对应于此次连接的套接字accept
v. 用返回的套接字和客户端进行通信rend/recv
vi. 返回,等待另一客户请求
vii. 关闭套接字
b)客户端程序:
i. 创建套接字socket
ii. 向服务端发出连接请求connect
iii. 和服务器端进行通信rend/recv
iv. 关闭套接字
18. 基于UDP的socket编程
a)服务器端(接收端)程序:
i. 创建套接字socket
ii. 将套接字绑定到一个本地地址和端口上bind
iii. 等待接收数据recv/from
iv. 关闭套接字
b)客户端(发送端)程序:
i. 创建套接字socket
ii. 向服务器发送数据sendto
iii. 关闭套接字
19.
int WSAStartup (
[code] WORD wVersionRequested, //打算使用的最高winsock版本号
[code] LPWSADATA lpWSAData //是个结构体,接收socket的详细信息
[code]);
20.
alt+F8
:格式化代码
21.
面向
TCP
的连接,服务器端
a)
套接字
[code]SOCKET socket (
[code] int af, //指定地址簇
[code] int type, //socket类型
[code] int protocol //协议
);
b)
绑定
[code]int bind (
[code] SOCKET s, //要绑定的套接字
[code] const struct sockaddr FAR* name, //指定了该套接字的本地地址信息
[code] int namelen//该地址结构的长度
[code]);
struct sockaddr {
u_short sa_family;
char sa_data[14];
};
c) 监听
[code]int listen (
[code] SOCKET s,
[code] int backlog
[code]);
d) 接受连接
[code]SOCKET accept (
[code] SOCKET s,
[code] struct sockaddr FAR* addr,
[code] int FAR* addrlen
[code]);
[code]e)
发送
[code]int send (
[code] SOCKET s, //建立连接的socket
[code] const char FAR * buf, //发送的数据
[code] int len, //发送数据的长度
[code] int flags
[code]);
[code]f)
接收
[code]int recv (
[code] SOCKET s,
[code] char FAR* buf,
[code] int len,
[code] int flags
[code]);
g) 需要的文件
#include <winsock2.h>
需要连接一个动态链接库:ws2_32.lib
22. 服务器端:
a)Socket
b)连接:connect
[code]int connect (
[code] SOCKET s,
[code] const struct sockaddr FAR* name,
[code] int namelen
[code]);
c) 接收:recv
d) 发送:send
e) 关闭:closesocket
23. Tcp服务端程序:
[cpp] view
plaincopy
#include <WINSOCK2.H>
#include <stdio.h>
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
listen(sockSrv,5);
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
while(1)
{
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
char sendBuf[100];
sprintf(sendBuf,"Welcome %s to 刘洼村",inet_ntoa(addrClient.sin_addr));
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
char recvBuf[100];
recv(sockConn,recvBuf,100,0);
printf("%s\n",recvBuf);
closesocket(sockConn);
}
}
24. Tcp客户端程序:
[cpp] view
plaincopy
#include <WINSOCK2.H>
#include <stdio.h>
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");//服务器端的地址
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
char recvBuf[100];
recv(sockClient,recvBuf,100,0);
printf("%s\n",recvBuf);
send(sockClient,"This is 刘洼村",strlen("This is 刘洼村")+1,0);
closesocket(sockClient);
WSACleanup();
}
25. 运行之后,开启了6个客户端,一个服务器端。程序运行效果:
26. 面向UDP的连接
27. 服务器:socket
a)bind
b)接收数据:
[code]int recvfrom (
[code] SOCKET s, //套接字
[code] char FAR* buf, //接收数据
[code] int len, //长度
[code] int flags, //会影响调用行为,0
[code] struct sockaddr FAR* from, //接收发送方的地址信息
[code] int FAR* fromlen //接收长度
[code]);
c) 关闭closesocket
d) Cleanup
28. UDP服务器端程序:
[cpp] view
plaincopy
#include <WINSOCK2.H>
#include <stdio.h>
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}
SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
char recvBuf[100];
recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
printf("%s\n",recvBuf);
closesocket(sockSrv);
WSACleanup();
}
28. UDP客户端:
a)socket定义
b)发送:
[code]int sendto (
[code] SOCKET s,
[code] const char FAR * buf,
[code] int len,
[code] int flags,
[code] const struct sockaddr FAR * to,
[code] int tolen
[code]);
29. UDP客户端程序
[cpp] view
plaincopy
#include <WINSOCK2.H>
#include <stdio.h>
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}
SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
sendto(sockClient,"Hello 刘洼村",strlen("Hello 刘洼村")+1,0,
(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
closesocket(sockClient);
WSACleanup();
}
运行结果:
30. 注意:每个程序都要加上ws2_32.lib链接库。如下添加:
By 刘洼村
相关文章推荐
- C++常用术语及其英文翻译的含义和简单用途总结(七)
- C++如何加载PNG透明图片作为菜单项的图标
- 编程算法 - 阅读完整的文件(C++)
- strcpy没有声明 c++头文件详解
- 从编译器角度分析C语言中数组名和指针的区别
- [leetcode-223]Rectangle Area(c++)
- c语言实现函数给主函数中的指针赋值的方法
- 5.7 C和C++的关系
- C++多态基础
- C与C++中结构体的区别
- C++中的四种类型转换
- [leetcode-225]Implement Stack using Queues(c++)
- C++中函数指针的使用
- C/C++:内存字节对齐详解
- 关于C语言头文件保护的一些认识
- c++经典好书
- C++基础细节(一)
- C++名字空间
- VC++编译链接原理与过程
- C++中的常量定义小结