socket编程解决网络数据的传输
来源:互联网 发布:手机淘宝论坛怎么找 编辑:程序博客网 时间:2024/05/22 03:46
socket编程我用的就是原生态的socket,今天也只是学了下原理,写了一个简单的小例子,听说websocket这个第三方库不错,这几天也想学学,看看怎么样吧。原生态的socket我第一次弄,中间出了不少的问题,我把他们都记录了下来,方便以后看吧。明天想移植到android上看看,解决一下编码的问题库的问题什么的,今天把他们的使用方法贴出来,大家可以参考一下。
1
#include "HelloWorldScene.h"
2
//需要包含目录E:\cocos2d-x-2.2\cocos2d-x-2.2\cocos2dx\platform\third_party\win32\pthread
3
#include "pthread.h"
4
5
//需要加入库ws2_32.lib
6
//在不同的平台下引入不同的头文件
7
#if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
8
#ifndef _WINSOCKAPI_
9
#define _WINSOCKAPI_
10
#ifndef _WINSOCK2API
11
#define _WINSOCK2API
12
#include <WinSock2.h>
13
#endif
14
#endif
15
#else
16
#include <sys/socket.h>
17
#include <netinet/in.h>
18
#include <sys/types.h>
19
#include <arpa/inet.h>
20
21
#endif
22
23
typedef
unsigned
int
SOCKET;
以上的代码是在头文件中的申明,这里要注意不同的平台需要包含不同的头文件,thread头文件还要附加包含路径,socket要引入库。
1
//服务器端的代码
2
void
HelloWorld::initSocket()
3
{
4
//在windows下要初始化socket库,以下代码本人也不知道含义,不过照抄好了
5
#if(CC_TARGET_PLATFORM==CC_PLATFORM_WIN32)
6
WORD
wVersionRequested;
7
WSADATA wsaData;
8
int
err;
9
wVersionRequested=MAKEWORD(1,1);
10
err=WSAStartup(wVersionRequested,&wsaData);
11
if
(err!=0){
12
return
;
13
}
14
if
(LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion)!=1){
15
WSACleanup();
16
return
;
17
}
18
#endif
19
20
//1、定义一个socket
21
//AF_INET ipv4协议 第二个参数代表是TCP通信还是UDP通信
22
//SCOK_STREAM是TCP通信,SCOK_DGRAM是UPD通信,第三个参数填0
23
//返回socket描述符,失败返回-1
24
SOCKET sockid = socket(AF_INET,SOCK_STREAM,0);
25
if
(sockid == -1)
26
{
27
CCLog(
"socket error"
);
28
this
->errorCode(sockid);
29
return
;
30
}
31
32
CCLog(
"%d"
,sockid);
33
34
//2 定义通信地址结构体
35
struct
sockaddr_in sockaddr;
36
//使用ipv4协议族
37
sockaddr.sin_family = AF_INET;
38
//htons将主机字节序转化为网络字节序,网络字节序统一采用大端格式,而有的主机使用的是小端模式
39
//所以要进行转换,sin_port代表的是端口号
40
sockaddr.sin_port = htons(8888);
41
//想要通信的网络地址
42
//inet_addr()将一个以.分割的字符串转化为一个网络地址
43
sockaddr.sin_addr.s_addr = inet_addr(
"127.0.0.1"
);
44
//以下这句话表示的就是本机的IP地址
45
//sockaddr.sin_addr.s_addr=htonl(INADDR_ANY);
46
47
//3 将socket和通信地址结构体绑定
48
if
(bind(sockid,(
struct
sockaddr *)&sockaddr,
sizeof
(
struct
sockaddr_in)) == -1)
49
{
50
//如果失败的话,根据不同的平台做不同的处理
51
CCLog(
"bind is error!"
);
52
this
->errorCode(sockid);
53
return
;
54
}
55
56
//4 监听 第二个参数设置请求排队的最大长度
57
//也就是说同一时刻有多个客户端程序可以和服务端相连, 使用这个表示可以接受的排队长度.
58
if
(listen(sockid,100) == -1)
59
{
60
CCLog(
"listen"
);
61
this
->errorCode(sockid);
62
return
;
63
}
64
65
CCLog(
"everying is ok! and accepting"
);
66
67
//一个死循环,用来不断接收多个客户端的请求
68
while
(1)
69
{
70
struct
sockaddr_in sockaddr_from;
71
int
len =
sizeof
(sockaddr_from);
72
//accept调用时,服务器端的程序会一直阻塞,直到有一个
73
//客户程序发出了连接,这里边的参数和bind函数的参数类似,后俩个参数是用来接受信息的
74
//这里要特别的注意,我让这个问题搞了俩个小时了,就是应该用client_socket接受accept返回的值
75
//这个值是用来和客户端通信的socket!
76
SOCKET client_socket;
77
if
((client_socket = accept(sockid,(
struct
sockaddr *)&sockaddr_from,&len)) == -1)
78
{
79
CCLog(
"accept error"
);
80
this
->errorCode(sockid);
81
return
;
82
}
83
//打印客户端的信息
84
CCLog(
"client %s accepted! port is %d"
,inet_ntoa(sockaddr_from.sin_addr),
85
ntohs(sockaddr_from.sin_port));
86
87
//创建一个线程,用来处理客户端的请求
88
pthread_t pthread_id;
89
pthread_create(&pthread_id,NULL,HelloWorld::doSomthing,(
void
*)client_socket);
90
char
* a[1];
91
pthread_join(pthread_id,(
void
**)a);
92
}
93
}
94
95
//处理客户端请求的操作写在这里
96
void
* HelloWorld::doSomthing(
void
* sock)
97
{
98
SOCKET sockid = (SOCKET)sock;
99
CCLog(
"%d"
,sockid);
100
char
buf[10];
101
int
len;
102
//最后一个参数一般设置为0
103
len = recv(sockid,buf,
sizeof
(buf),0);
104
if
(-1 != len)
105
{
106
//将客户端的数据打印出来
107
CCLog(
"%d"
,len);
108
CCLog(
"%s"
,buf);
109
}
110
else
111
{
112
CCLog(
"recv failed!"
);
113
pthread_exit((
void
*)-1);
114
}
115
116
return
0;
117
}
118
119
//socket不成功调用的失败代码
120
void
HelloWorld::errorCode(SOCKET sockid)
121
{
122
#if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
123
closesocket(sockid);
124
WSACleanup();
125
#else
126
close(sockid);
127
#endif
128
return
;
129
}
1
//客户端代码
2
void
HelloWorld::menuCloseCallback(CCObject* pSender)
3
{
4
//在windows下要初始化socket库,以下代码本人也不知道含义,不过照抄好了
5
#if(CC_TARGET_PLATFORM==CC_PLATFORM_WIN32)
6
WORD
wVersionRequested;
7
WSADATA wsaData;
8
int
err;
9
wVersionRequested=MAKEWORD(1,1);
10
err=WSAStartup(wVersionRequested,&wsaData);
11
if
(err!=0){
12
return
;
13
}
14
if
(LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion)!=1){
15
WSACleanup();
16
return
;
17
}
18
#endif
19
20
SOCKET sockid = socket(AF_INET,SOCK_STREAM,0);
21
22
struct
sockaddr_in sockaddr;
23
sockaddr.sin_family = AF_INET;
24
//地址需要写服务器端的地址
25
sockaddr.sin_addr.s_addr = inet_addr(
"127.0.0.1"
);
26
//端口号和服务器的端口号相同
27
sockaddr.sin_port = htons(8888);
28
int
len =
sizeof
(
struct
sockaddr_in);
29
30
//客户端使用的函数是connect()
31
if
(connect(sockid,(
struct
sockaddr *)&sockaddr,len) == -1)
32
{
33
CCLog(
"accept error"
);
34
#if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
35
closesocket(sockid);
36
WSACleanup();
37
#else
38
close(sockid);
39
#endif
40
return
;
41
}
42
CCLog(
"client connect is ok!"
);
43
static
int
i = 1;
44
CCString * str = CCString::createWithFormat(
"%d client"
,i++);
45
//最后一个参数写0就可以了
46
int
len2 = send(sockid,str->getCString(),str->length(),0);
47
if
(len2 != -1)
48
{
49
CCLog(
"send %d bytes"
,len2);
50
}
51
else
52
{
53
CCLog(
"send failure!"
);
54
}
55
}
以上代码的含义我注释的已经非常清楚了,有不懂的可以问我,对于线程的那部分可以看看我以前的文章。在这个过程中我也走了不少的歪路,希望我们共同学习!
0 0
- socket编程解决网络数据的传输
- 数据的网络传输
- [转帖]socket 网络编程 点对点传输文件
- VC++使用Socket网络编程传输文件
- socket网络编程 两类传输协议
- 网络数据(socket)传输总结
- 网络数据(socket)传输总结
- 网络数据(socket)传输总结
- 通过socket网络传输数据原理分析
- 网络编程中何时转换传输数据的字节序
- C#网络编程,传输数据的3种方式
- C#网络编程,传输数据的3种方式
- 网络编程:基于TCP的socket网络传输视频(C++, python)
- 网络编程 UDP TCP传输数据
- Socket的网络编程
- java--基于socket的网络传输开发
- socket传输中文出现乱码的解决
- Python的struct使用-解决socket的通讯限制了传输数据的长度
- BestCoder Round #6
- ClassCastException深入分析
- Spring属性占位符PropertyPlaceholderConfigurer的使用
- Linux中su、su -和sudo的区别
- axure视频学习地址
- socket编程解决网络数据的传输
- hdu 4750 Count The Pairs
- 对彩色图像进行色彩通道信息的分割
- 跟着鬼哥学Android java hook (一)
- java webservice 用户验证 (服务端 + 客户端)
- android——文件目录选择
- Balloon Comes!
- Devexpress控件之TreeList的初始赋值和勾选值保存
- pdf文件转换器的使用方法和下载地址