我想从我的TCP服务器一次只允许一个连接.你能告诉我,如何使用没有积压长度为零的听力.
我正在使用代码(如下所示),但是当我逐个启动2个客户端时,两者都会连接起来.我使用VC++和winsock2.
听(m_socket,-1);
因积压而传递零也无法正常工作.
等待你的回复.
问候,
immi
一些代码和相关的警告/错误:
#include <windows.h>
#include <iphlpapi.h>
int main() { }
Run Code Online (Sandbox Code Playgroud)
F:/Prog/mingw-w64/x86_64-4.9.2-win32-seh-rt_v3-rev1/mingw64/x86_64-w64-mingw32/include/ws2ipdef.h:71:3:错误:'
ADDRESS_FAMILY'没有命名类型Run Code Online (Sandbox Code Playgroud)ADDRESS_FAMILY si_family;
#include <windows.h>
#include <winsock2.h>
#include <iphlpapi.h>
int main() { } // this compiles successfully, only gives warning
Run Code Online (Sandbox Code Playgroud)
F:/Prog/mingw-w64/x86_64-4.9.2-win32-seh-rt_v3-rev1/mingw64/x86_64-w64-mingw32/include/winsock2.h:15:2:警告:#warning请包含winsock2.h在windows.h之前[-Wcpp]
#include <winsock2.h>
#include <windows.h>
#include <iphlpapi.h>
int main() { }
Run Code Online (Sandbox Code Playgroud)
(汇编成功).
我的问题是:
iphlpapi.h(以及依赖于winsock的其他文件)#include <winsock2.h>自己做,或者至少提供更好的错误消息?windows.h呢?我正在尝试使用c ++中的WinSock2.h进行UDP Flood,但是仅在WinSock2.h上我收到了70多个错误和17条警告,所有错误都是重新定义,ws2def.h中的语法错误以及“不同的链接” 。我是在做错什么,还是WinSock2有问题?如果有什么用,我正在使用64位Windows 10,Visual Studio 2015
#include "stdafx.h"
#include <WinSock2.h>
#include <windows.h>
#include <fstream>
#include <time.h>
#include "wtypes.h"
#include "Functions.h"
#pragma comment(lib, "ws2_32.lib")
//Get IP
cin.getline(TargetIP, 17);
//Get IP
cout << "Enter the Port: ";
cin >> nPort;
cout << endl;
//Initialize WinSock 2.2
WSAStartup(MAKEWORD(2, 2), &wsaData);
//Create our UDP Socket
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
//Setup the target address
targetAddr.sin_family = AF_INET;
targetAddr.sin_port = htons(nPort);
targetAddr.sin_addr.s_addr = inet_addr(TargetIP);
//Get input from user
cout << "Please specify the buffer …Run Code Online (Sandbox Code Playgroud) 我正在尝试在连接时自动向客户端发送服务器请求,但我一直得到10057的WSAGetLastError.我已经设置了从客户端到服务器的请求没有问题所以我不明白为什么我不能反过来?也许服务器必须等待来自客户端的第一个'发送',但我不明白为什么会这样?
我使用的是:
-asynchronous插座
-TCP
-s是一个有效的套接字
-i'v循环RequestInfo了若干遍,但没有任何变化
-选择()返回0
-datasize返回-1,ERRCODE 10057
谢谢 !!!
服务器:
//first - following the debugger
FD_ACCEPT
int acc = accept(s, (struct sockaddr*)&fromm, &fromlenn); //success
if(acc <= 0)
{
eLOGG << "\nFAIL FD_ACCEPT: " << WSAGetLastError();
}
RequestInfo();
//then
RequestInfo()
{
stringstream ssConverter;
ssConverter.clear(); ssConverter.str(string());
ssConverter << "00aa"; //request signal
bool blogin = false;
eLOG << "signal is: *" << ssConverter.str() << "*";
int bufSize = ssConverter.str().length();
fd_set writefds;
struct timeval timeout;
timeout.tv_sec = 3;
timeout.tv_usec = 0;
FD_ZERO(&writefds); …Run Code Online (Sandbox Code Playgroud) 先写代码
DWORD WINAPI tcp_t(LPVOID lpParam)
{
SOCKET tcp_client_s = (SOCKET)lpParam;
struct sockaddr_in tcp_client;
int tcp_client_len = sizeof(tcp_client), length;
char req[4096], resp[4096];
getpeername(tcp_client_s, (struct sockaddr *)&tcp_client, &tcp_client_len);
cli_log(PROTO_TCP, LOG_SYS, "(%s:%d) TCP thread spawned\n", inet_ntoa(tcp_client.sin_addr), ntohs(tcp_client.sin_port));
length = get_req_tcp(tcp_client_s, req, tcp_client);
if(strci(req, "GET /syachi2ds/web/", 0))
{
while(!strstr(req, "Connection: close\r\n\r\n"))
length += get_req_tcp(tcp_client_s, req + length, tcp_client);
length = check_req(req, resp);
if(length > 0)
send_resp_tcp(tcp_client_s, resp, length, tcp_client);
}
closesocket(tcp_client_s);
cli_log(PROTO_TCP, LOG_SYS, "(%s:%d) socket closed, closing thread\n", inet_ntoa(tcp_client.sin_addr), ntohs(tcp_client.sin_port));
ExitThread(0);
}
int get_req_tcp(SOCKET …Run Code Online (Sandbox Code Playgroud) 我试图将客户端倍增,并将其发送给每个客户端.但它只适用于一个,在一个客户端连接服务器后,只是无法用于传入连接.
while(true)
{
if(Sub = accept(Socket, (sockaddr*)&IncomingAddress, &AddressLen))
{
for(int i = 0; i < MaxUsers; i++)
{
if(!ClientAddress[i].sin_family)
{
ClientAddress[i] = IncomingAddress;
char Version[128], Dir[256], Path[256], URL[128], Message[256];
GetCurrentDirectory(256, Dir);
sprintf(Path, "%s\\Version.ini", Dir);
GetPrivateProfileString("Default", "Version", "1.0.0.0", Version, 128, Path);
GetPrivateProfileString("Default", "URL", "", URL, 128, Path);
GetPrivateProfileString("Default", "Message", "", Message, 256, Path);
send(Sub, Version, 128, 0);
send(Sub, Message, 256, 0);
break;
}
}
continue;
}
}
Run Code Online (Sandbox Code Playgroud) 在Windows的C API中,如何获取网络接口名称列表?(相当于getifaddrs()Linux)
该WSAIoctl(sock, SIO_GET_INTERFACE_LIST_EX, ...)函数似乎只返回IP地址,加上一些元数据.
我从二进制文件中查看了UDP客户端程序,我能够将一个UDP数据包发送到UDP服务器,这是我的嵌入式设备,该设备回送UDP消息.
在这个PC-UDP客户端代码中,它应该得到回显的消息,但我没有得到任何回声.所以我在我的PC上运行一个UDP服务器,它监听传入的数据并打印它,我能够看到来自我的嵌入式设备的回显消息.
当我在代码中的while(1)循环之前添加这些行时,现在我能够看到Echoed返回消息.
//setup address structure
memset((char *) &si_server, 0, sizeof(si_server));
si_server.sin_family = AF_INET;
si_server.sin_port = htons(PORT);
si_server.sin_addr.S_un.S_addr = INADDR_ANY;
if( bind(s ,(struct sockaddr *)&si_server , sizeof(si_server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d" , WSAGetLastError());
exit(EXIT_FAILURE);
}
puts("Bind done");
Run Code Online (Sandbox Code Playgroud)
有关可能导致问题的原因的任何想法?
我有一个使用 Indy 的客户端和服务器套接字应用程序,用 Delphi 10.2 编译。
应用程序有一个工作线程,用于处理来自不同端口的请求,并使用对以下内容的调用在同一线程中写入响应:
procedure TMyCommManager.WriteResponse(AHandler: TIdIOHandler; SomeData: SomeType);
var
idBytes: TidBytes;
PacketSize: Integer;
begin
SomeData.GetBytes(idBytes, PacketSize);
AHandler.Write(DataBuffer, PacketSize);
end;
Run Code Online (Sandbox Code Playgroud)
几乎所有时间一切都按预期工作,但我们注意到工作线程在生产中不时冻结。经过多次迭代,我们终于明白所有这些都发生在对 的调用中TidIOHandler.Write(),我很确定它正在发生,因为单个端口的另一端没有从套接字读取响应。
从另一端重置到端口后,工作线程解冻并按预期继续工作。
我从 Remy Lebeau找到了这个问题的答案Delphi (Indy) Server Freezing on Write,他在评论中提到(强调我的):
Indy 使用阻塞套接字,因此如果客户端没有在其端读取入站数据,最终套接字的内部发送缓冲区将填满,并且套接字将在服务器端阻塞,等待客户端清空缓冲区。在这种情况下避免死锁的唯一方法是直接使用套接字 API 设置套接字级发送超时。Indy 没有在其逻辑中实现发送超时。
我正在寻找设置超时的正确方法,通过 INDY 或通过 Windows 中的直接 API 调用,但我陷入了困境,所以我来这里寻求帮助。
如果这是不可能的,我可以在辅助线程上实现超时机制,但我不确定从我端的辅助线程重置连接以让工作线程继续工作的正确方法是什么。