Cocos2dx网络学习笔记(一)
来源:互联网 发布:什么是淘宝企业店铺 编辑:程序博客网 时间:2024/06/14 22:42
Cocos2dx网络学习笔记(一)
学习资料
C++ Socket 编程
简单的服务器
直接上代码,再一一解释用到的东西
#include <string>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <iostream>using namespace std;#define SOCKET int#define ListenPort 9999int main(){ SOCKET st = socket( AF_INET, SOCK_STREAM, 0 ); if ( st == -1 ) { cout << "create socket failed" << endl; return 0; } struct sockaddr_in my_addr; my_addr.sin_family = AF_INET; my_addr.sin_port = htons( ListenPort ); my_addr.sin_addr.s_addr = INADDR_ANY; /* inet_addr("127.0.0.1"); */ memset( my_addr.sin_zero, 0, 8 ); int result = ::bind( st, (struct sockaddr *) (&my_addr), sizeof(struct sockaddr) ); if ( result == -1 ) { cout << "bind socket failed" << endl; return 0; } result = listen( st, 1 ); if ( result == -1 ) { cout << "listen socket failed" << endl; return 0; } struct sockaddr_in new_addr; socklen_t sin_size = sizeof(struct sockaddr_in); SOCKET new_connect = accept( st, (struct sockaddr *) (&new_addr), &sin_size ); if ( new_connect != -1 ) { char* ip = inet_ntoa( new_addr.sin_addr ); cout << "new connect from " << ip << " with port:" << new_addr.sin_port << endl; char buf[1024]; while ( true ) { int recv_bytes = ::recv( new_connect, &buf, 1024, 0 ); if ( recv_bytes == -1 ) { cout << "recv failed" << endl; break; } cout << "receive from client:" << buf << endl; string message = buf; message = "this is reply for " + message; int reply_len = message.length(); int send_bytes = ::send( new_connect, message.c_str(), reply_len, 0 ); if ( send_bytes == -1 ) { cout << "send failed" << endl; break; } } } return 0;}
首先是头文件:
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>
这几个基本是常用的,其他常用的网络头文件可以看这个 linux网络编程常用头文件, windows下是
#include <winsock.h>
int socket(int domain, int type, int protocol);
创建一个socket,第一个和第三个参数分别是域和协议,一般直接用这个就好,第二个参数是使用哪种协议,SOCK_STREAM
是TCP,SOCK_DGRAM
是UDP的,返回值为-1表示创建失败struct sockaddr_in
这个结构体是为了更方便的处理sockaddr
的,添加监听、连接服务器的相关配置都是这个结构体,两者可以强转,原型是struct sockaddr_in { short int sin_family; /* 通信类型,跟创建socket的第1个参数一致 */ unsigned short int sin_port; /* 端口 */ struct in_addr sin_addr; /* Internet 地址 struct in_addr { unsigned long s_addr; };*/ unsigned char sin_zero[8]; /* 与sockaddr结构的长度相同*/};
因为网络和本机的字节顺序不一样,
sin_port
需要通过htons
(host to network short)转换, ip地址也需要转换,不过可以使用专门的函数inet_addr("ip")
,特别的,INADDR_ANY
表示本机地址。sin_zero
需要用memset
或者bzero
清零。int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
绑定端口,第1个参数是创建的socket;第二个参数可以用sockaddr_in,绑定哪个端口也是这个参数指定;addrlen直接用sizeof(struct sockaddr)
。绑定失败(如端口占用等)返回值为-1。int listen(int sockfd, int backlog);
socket开始监听,backlog表示最多可接收的连接数,可根据服务器性能设置int accept(int sockfd, void *addr, int *addrlen);
开始接听后调用accept会阻塞,直至有一个新连接到来。返回值是新连接的socket,你可以使用这个socket去接受和发送消息。void *addr
可以获取新连接的参数,如IP,端口等。后两个参数跟bind类似。注意一点,获取到的参数信息是网络字节顺序,需要转换成本机自己顺序才可正确使用,ntohs
(network to host short)和inet_ntoa
。int recv(int sockfd, void *buf, int len, unsigned int flags);
接收sockfd的消息,默认是阻塞式。新消息内容将被存储到buf, len是buf可存储的最大数量,flags可设置为0,返回值是实际接收了多少数据。错误返回-1,断开连接等通常返回0int send(int sockfd, const void *msg, int len, int flags);
给sockfd发送消息,阻塞。msg是消息内容,len是需要发送的消息长度,flags可设置为0.返回值是实际发送了多少内容。- 注意事项: std中也有recv和send函数,在recv前面加::可以表明是使用socket的recv。在
using namespace std;
的情况下要特别注意. - 可以使用终端命令
telnet 127.0.0.1 9999
测试
简单的客户端
bind
、listen
和accept
都是服务器端用的函数,客户端用的就只需要一个connect
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
创建socket完成后调用此函数,serv_addr是服务器的地址和端口。错误返回-1
示例代码:
#include <string>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <iostream>using namespace std;#define SOCKET int#define ListenPort 9999using namespace std;int main(int argc, char *argv[]) { SOCKET st = socket( AF_INET, SOCK_STREAM, 0 ); if ( st == -1 ) { cout << "create socket failed" << endl; return 0; } struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons( ListenPort ); server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");; memset( server_addr.sin_zero, 0, 8 ); int result = connect(st, (struct sockaddr*)(&server_addr), sizeof(struct sockaddr)); if (result == -1) { cout << "connect server failed" << endl; return 0; } string message; while (true) { cin >> message; cout << "send to server:" << message << endl; int reply_len = message.length(); int send_bytes = ::send( st, message.c_str(), reply_len, 0 ); if ( send_bytes == -1 ) { cout << "send failed" << endl; break; } char buf[1024]; int recv_bytes = ::recv( st, &buf, 1024, 0 ); if ( recv_bytes == -1 ) { cout << "recv failed" << endl; break; } cout << "receive from server:" << buf << endl; } return 0;}
运行结果
服务器 + telnet
服务器 + 客户端
0 0
- Cocos2dx网络学习笔记(一)
- cocos2dx学习笔记(一)
- cocos2dx学习笔记一
- cocos2dx学习笔记(一)环境搭建
- Cocos2dx学习笔记(一)创建项目
- cocos2dx 3.3 之学习笔记(一)
- cocos2dx源码学习笔记一(Image)
- cocos2dx 3.x学习笔记(一)
- cocos2dx游戏开发学习笔记(一)
- 网络学习笔记(一)
- 网络学习笔记(一)
- 网络学习笔记(网络层一)
- 【cocos2dx学习笔记】HttpClient网络请求
- cocos2dx-js学习笔记(一)环境搭建
- cocos2dx学习笔记(cocos2dx特效)
- cocos2dx学习笔记(cocos2dx特效)
- 【cocos2dx】cocos2dx学习笔记
- cocos2dx 3.0学习笔记(一):Win32下-cocos2dx-3.0环境配置和创建项目
- Dynamics CRM 视图显示列的拷贝—view layout replicator
- Eclipse使用gradle的配置
- 华为机试——从5个人中选取2个人作为礼仪
- 深入浅出设计模式(四):6.创建者模式
- 如何在自己的项目中引入tinymce富文本编辑器
- Cocos2dx网络学习笔记(一)
- android软键盘操作
- 数据库锁的基本原理
- JavaScript之Date
- 命令行下执行php脚本
- AdBlock Plus安装
- java微信接口开发java SpringMVC mybatis 后台框架
- Oracle批量重建索引
- PackageManagerService(Android5.1)深入分析(二)处理permission文件