设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 1617|回复: 1
打印 上一主题 下一主题

[已经解决] C开发网络化插件问题

[复制链接]

Lv1.梦旅人

梦石
0
星屑
155
在线时间
332 小时
注册时间
2013-7-6
帖子
356
跳转到指定楼层
1
发表于 2015-3-17 00:38:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 wolves 于 2015-3-17 00:40 编辑

用C语言编译一个网络化的小插件,但是在制作过程中发现了些问题没办法解决:
1. recv函数默认是阻塞的,如果调用时没收到数据会一直等待,造成RM调用卡死。如果设置成非阻塞的话很可能会丢失数据。
2. 服务端收到客户端的数据后没有办法连续发送这个数据,否则会接收不到这条信息后的数据
下面是C#的dll代码:
(link库里要加一个ws2_32.lib,否则连接会出错)
  1. #include <Winsock2.h>
  2. #include <stdio.h>

  3. char s[100],*mes=s;
  4. char t[20],*ip=t;
  5. extern "C" char __declspec(dllexport) *sendmes(char *mes,char *ip,long port)
  6. {
  7.     //固定格式
  8.     WORD wVersionRequested;
  9.     WSADATA wsaData;
  10.     int err;
  11.    
  12.     wVersionRequested = MAKEWORD( 1, 1 );
  13.    
  14.     err = WSAStartup( wVersionRequested, &wsaData );
  15.     if ( err != 0 ) {
  16.         return "{Error}";
  17.     }
  18.    

  19.     if ( LOBYTE( wsaData.wVersion ) != 1 ||
  20.         HIBYTE( wsaData.wVersion ) != 1 ) {
  21.         WSACleanup( );
  22.         return "{Error}";
  23.     }

  24.     //建立通讯socket
  25.     SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);

  26.     SOCKADDR_IN addrSrv;
  27.     addrSrv.sin_addr.S_un.S_addr=inet_addr(ip);//设定需要连接的服务器的ip地址
  28.     addrSrv.sin_family=AF_INET;
  29.     addrSrv.sin_port=htons(port);//设定需要连接的服务器的端口地址
  30.     connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//与服务器进行连接
  31.    
  32.    
  33.     //发送信息
  34.     send(sockClient,mes,strlen(mes)+1,0);
  35.     //接
  36.     char recvBuf[100];
  37.     recv(sockClient,recvBuf,100,0);
  38.         strcpy(mes,recvBuf);
  39.         return mes;
  40.     closesocket(sockClient);
  41.     WSACleanup();
  42. }
  43. extern "C" char __declspec(dllexport) *getmes(char *ip,long port)
  44. {
  45.     //固定格式
  46.     WORD wVersionRequested;
  47.     WSADATA wsaData;
  48.     int err;
  49.    
  50.     wVersionRequested = MAKEWORD( 1, 1 );
  51.    
  52.     err = WSAStartup( wVersionRequested, &wsaData );
  53.     if ( err != 0 ) {
  54.         return "{Error}";
  55.     }
  56.    

  57.     if ( LOBYTE( wsaData.wVersion ) != 1 ||
  58.         HIBYTE( wsaData.wVersion ) != 1 ) {
  59.         WSACleanup( );
  60.         return "{Error}";
  61.     }

  62.     //建立通讯socket
  63.     SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);

  64.         int nNetTimeout=2000;
  65.         setsockopt(sockClient,SOL_SOCKET,SO_RCVTIMEO,(char*)&nNetTimeout,sizeof(int));

  66.     SOCKADDR_IN addrSrv;
  67.     addrSrv.sin_addr.S_un.S_addr=inet_addr(ip);//设定需要连接的服务器的ip地址
  68.     addrSrv.sin_family=AF_INET;
  69.     addrSrv.sin_port=htons(port);//设定需要连接的服务器的端口地址
  70.     connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//与服务器进行连接

  71.     //接
  72.     char recvBuf[100];
  73.     if(recv(sockClient,recvBuf,100,0)>0)
  74.                 strcpy(mes,recvBuf);
  75.         else
  76.                 strcpy(mes,"{Error}");
  77.     closesocket(sockClient);
  78.     WSACleanup();
  79.         return mes;
  80. }
复制代码
服务端代码:
  1. #include <Winsock2.h>
  2. #include <stdio.h>

  3. void main()
  4. {
  5.     // 以下的几句都是固定的
  6.     WORD wVersionRequested;
  7.     WSADATA wsaData;
  8.     int err;
  9.    
  10.     wVersionRequested = MAKEWORD( 1, 1 );
  11.    
  12.     err = WSAStartup( wVersionRequested, &wsaData );//该函数的功能是加载一个Winsocket库版本
  13.     if ( err != 0 ) {
  14.         return;
  15.     }
  16.    

  17.     if ( LOBYTE( wsaData.wVersion ) != 1 ||
  18.         HIBYTE( wsaData.wVersion ) != 1 ) {
  19.         WSACleanup( );
  20.         return;
  21.     }

  22.     unsigned short port;
  23.     //真正socket编程部分
  24.     SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);//面向连接的可靠性服务SOCK_STRAM

  25.     SOCKADDR_IN addrSrv;//存放本地地址信息的
  26.     addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//htol将主机字节序long型转换为网络字节序
  27.     addrSrv.sin_family=AF_INET;
  28.         printf("请输入端口号");
  29.         scanf("%u",&port);
  30.     addrSrv.sin_port=htons(port);//htos用来将端口转换成字符,1024以上的数字即可

  31.     bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//将socket绑定到相应地址和端口上

  32.     listen(sockSrv,5);//等待队列中的最大长度为5

  33.     SOCKADDR_IN addrClient;
  34.     int len=sizeof(SOCKADDR);
  35.     printf("\n服务器已开启,信息如下:\n");
  36.     while(1)
  37.     {
  38.         SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);//建立一个新的套接字用于通信,不是前面的监听套接字

  39.         char recvBuf[100];
  40.         recv(sockConn,recvBuf,101,0);//服务器从客户端接受数据
  41.         printf("\n%s\n",recvBuf);
  42.         
  43.                 char sendBuf[100];
  44.                 sendBuf[0]='\0';
  45.         strcpy(sendBuf,recvBuf);
  46.         send(sockConn,sendBuf,strlen(sendBuf)+1,0);//服务器向客户端发送数据
  47.                 closesocket(sockConn);//关闭socket
  48.     }
  49. }
复制代码
求助
@RyanBern @myownroc  

点评

我试试  发表于 2015-3-17 13:58
异步线程  发表于 2015-3-17 09:47
偶是熬夜学编程的傻子

Lv1.梦旅人

梦石
0
星屑
155
在线时间
332 小时
注册时间
2013-7-6
帖子
356
2
 楼主| 发表于 2015-3-17 17:59:50 | 只看该作者
终于解决了,谢谢晴兰
偶是熬夜学编程的傻子
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-9-22 19:35

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表