赞 | 3 |
VIP | 21 |
好人卡 | 10 |
积分 | 2 |
经验 | 32573 |
最后登录 | 2024-6-13 |
在线时间 | 332 小时 |
Lv1.梦旅人
- 梦石
- 0
- 星屑
- 155
- 在线时间
- 332 小时
- 注册时间
- 2013-7-6
- 帖子
- 356
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
本帖最后由 wolves 于 2015-3-17 00:40 编辑
用C语言编译一个网络化的小插件,但是在制作过程中发现了些问题没办法解决:
1. recv函数默认是阻塞的,如果调用时没收到数据会一直等待,造成RM调用卡死。如果设置成非阻塞的话很可能会丢失数据。
2. 服务端收到客户端的数据后没有办法连续发送这个数据,否则会接收不到这条信息后的数据
下面是C#的dll代码:
(link库里要加一个ws2_32.lib,否则连接会出错)- #include <Winsock2.h>
- #include <stdio.h>
- char s[100],*mes=s;
- char t[20],*ip=t;
- extern "C" char __declspec(dllexport) *sendmes(char *mes,char *ip,long port)
- {
- //固定格式
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
-
- wVersionRequested = MAKEWORD( 1, 1 );
-
- err = WSAStartup( wVersionRequested, &wsaData );
- if ( err != 0 ) {
- return "{Error}";
- }
-
- if ( LOBYTE( wsaData.wVersion ) != 1 ||
- HIBYTE( wsaData.wVersion ) != 1 ) {
- WSACleanup( );
- return "{Error}";
- }
- //建立通讯socket
- SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
- SOCKADDR_IN addrSrv;
- addrSrv.sin_addr.S_un.S_addr=inet_addr(ip);//设定需要连接的服务器的ip地址
- addrSrv.sin_family=AF_INET;
- addrSrv.sin_port=htons(port);//设定需要连接的服务器的端口地址
- connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//与服务器进行连接
-
-
- //发送信息
- send(sockClient,mes,strlen(mes)+1,0);
- //接
- char recvBuf[100];
- recv(sockClient,recvBuf,100,0);
- strcpy(mes,recvBuf);
- return mes;
- closesocket(sockClient);
- WSACleanup();
- }
- extern "C" char __declspec(dllexport) *getmes(char *ip,long port)
- {
- //固定格式
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
-
- wVersionRequested = MAKEWORD( 1, 1 );
-
- err = WSAStartup( wVersionRequested, &wsaData );
- if ( err != 0 ) {
- return "{Error}";
- }
-
- if ( LOBYTE( wsaData.wVersion ) != 1 ||
- HIBYTE( wsaData.wVersion ) != 1 ) {
- WSACleanup( );
- return "{Error}";
- }
- //建立通讯socket
- SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
- int nNetTimeout=2000;
- setsockopt(sockClient,SOL_SOCKET,SO_RCVTIMEO,(char*)&nNetTimeout,sizeof(int));
- SOCKADDR_IN addrSrv;
- addrSrv.sin_addr.S_un.S_addr=inet_addr(ip);//设定需要连接的服务器的ip地址
- addrSrv.sin_family=AF_INET;
- addrSrv.sin_port=htons(port);//设定需要连接的服务器的端口地址
- connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//与服务器进行连接
- //接
- char recvBuf[100];
- if(recv(sockClient,recvBuf,100,0)>0)
- strcpy(mes,recvBuf);
- else
- strcpy(mes,"{Error}");
- closesocket(sockClient);
- WSACleanup();
- return mes;
- }
复制代码 服务端代码:- #include <Winsock2.h>
- #include <stdio.h>
- void main()
- {
- // 以下的几句都是固定的
- WORD wVersionRequested;
- WSADATA wsaData;
- int err;
-
- wVersionRequested = MAKEWORD( 1, 1 );
-
- err = WSAStartup( wVersionRequested, &wsaData );//该函数的功能是加载一个Winsocket库版本
- if ( err != 0 ) {
- return;
- }
-
- if ( LOBYTE( wsaData.wVersion ) != 1 ||
- HIBYTE( wsaData.wVersion ) != 1 ) {
- WSACleanup( );
- return;
- }
- unsigned short port;
- //真正socket编程部分
- SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);//面向连接的可靠性服务SOCK_STRAM
- SOCKADDR_IN addrSrv;//存放本地地址信息的
- addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//htol将主机字节序long型转换为网络字节序
- addrSrv.sin_family=AF_INET;
- printf("请输入端口号");
- scanf("%u",&port);
- addrSrv.sin_port=htons(port);//htos用来将端口转换成字符,1024以上的数字即可
- bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//将socket绑定到相应地址和端口上
- listen(sockSrv,5);//等待队列中的最大长度为5
- SOCKADDR_IN addrClient;
- int len=sizeof(SOCKADDR);
- printf("\n服务器已开启,信息如下:\n");
- while(1)
- {
- SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);//建立一个新的套接字用于通信,不是前面的监听套接字
- char recvBuf[100];
- recv(sockConn,recvBuf,101,0);//服务器从客户端接受数据
- printf("\n%s\n",recvBuf);
-
- char sendBuf[100];
- sendBuf[0]='\0';
- strcpy(sendBuf,recvBuf);
- send(sockConn,sendBuf,strlen(sendBuf)+1,0);//服务器向客户端发送数据
- closesocket(sockConn);//关闭socket
- }
- }
复制代码 求助
@RyanBern @myownroc |
|