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 
23typedef unsigned int SOCKET;

以上的代码是在头文件中的申明,这里要注意不同的平台需要包含不同的头文件,thread头文件还要附加包含路径,socket要引入库。

查看源代码
打印帮助
1//服务器端的代码
2void HelloWorld::initSocket()
3{
4    //在windows下要初始化socket库,以下代码本人也不知道含义,不过照抄好了
5    #if(CC_TARGET_PLATFORM==CC_PLATFORM_WIN32)
6        WORDwVersionRequested;
7        WSADATA wsaData;
8        interr;
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    structsockaddr_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,(structsockaddr *)&sockaddr,sizeof(structsockaddr_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        structsockaddr_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,(structsockaddr *)&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//处理客户端请求的操作写在这里
96void * HelloWorld::doSomthing(void * sock)
97{
98    SOCKET sockid = (SOCKET)sock;
99    CCLog("%d",sockid);
100    charbuf[10];
101    intlen;
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    return0;
117}
118 
119//socket不成功调用的失败代码
120void 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//客户端代码
2void HelloWorld::menuCloseCallback(CCObject* pSender)
3{
4    //在windows下要初始化socket库,以下代码本人也不知道含义,不过照抄好了
5    #if(CC_TARGET_PLATFORM==CC_PLATFORM_WIN32)
6        WORDwVersionRequested;
7        WSADATA wsaData;
8        interr;
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    structsockaddr_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    intlen = sizeof(structsockaddr_in);
29 
30    //客户端使用的函数是connect()
31    if(connect(sockid,(structsockaddr *)&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    staticint i = 1;
44    CCString * str = CCString::createWithFormat("%d client",i++);
45    //最后一个参数写0就可以了
46    intlen2 = 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}

以上代码的含义我注释的已经非常清楚了,有不懂的可以问我,对于线程的那部分可以看看我以前的文章。在这个过程中我也走了不少的歪路,希望我们共同学习!

socket编程解决网络数据的传输

0 0
原创粉丝点击