gpt4 book ai didi

c - Windows C套接字: select() gives WSAENOTSOCK error

转载 作者:行者123 更新时间:2023-11-30 18:37:20 26 4
gpt4 key购买 nike

我正在使用winsock 连接到远程服务器。我成功连接了套接字,但是当我尝试使用 select 获取套接字详细信息时,它说套接字不存在(WSAENOTSOCK)。

注意:我正在将这段代码作为 Visual studio win 控制台应用程序执行,我的操作系统是 Windows 8。

我的代码(假设代码执行从 run_client 函数开始,并且测试结构具有所有选项)。另外,函数位于不同的文件中,因此我需要多次调用 WSAStartup

#define _CRT_SECURE_DEPRECATE_MEMORY
#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <signal.h>
#include <sys/types.h>
#include <Winsock2.h>
#include <memory.h>
#include <WS2tcpip.h>

#pragma comment(lib,"ws2_32.lib")

int run_client(struct test * test)
{
int startup;
int result = 0;
fd_set read_set, write_set, excep_fd;
struct timeval now;
struct timeval* timeout = NULL;
struct iperf_stream *sp;

FD_ZERO(&excep_fd);

if (soc_connect(test) < 0)
return -1;

printf("Run client : success in making socket\n");

memcpy(&read_set, &test->read_set, sizeof(fd_set));
memcpy(&write_set, &test->write_set, sizeof(fd_set));

int iResult;
WSADATA wsaData;

iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return -1;
}

if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
printf("Could not find a usable version of Winsock.dll\n");
WSACleanup();
return -1;
}
else
{
printf("The Winsock 2.2 dll was found okay\n");
}


struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;

result = select(test->ctrl_sck + 1, &read_set, 0, 0, &tv);

if (SOCKET_ERROR == result)
{
switch (WSAGetLastError())
{
case WSANOTINITIALISED:
printf("select_result error : WSANOTINITIALISED\n");
break;
case WSAEFAULT:
printf("select_result error : WSAEFAULT\n");
break;
case WSAENETDOWN:
printf("select_result error : WSAENETDOWN\n");
break;
case WSAEINTR:
printf("select_result error : WSAEINTR\n");
break;
case WSAEINPROGRESS:
printf("select_result error : WSAEINPROGRESS\n");
break;
case WSAENOTSOCK:
printf("select_result error : WSAENOTSOCK\n");
break;
default:
printf("select_result errors : %d\n", WSAGetLastError());
break;
}
i_errno = WSAGetLastError();
closesocket(test->ctrl_sck);
WSACleanup();
return -1;
}
else if (result == 0)
{
printf("select_result : timeout : %d\n", result);
WSACleanup();
return -1;
}
else
{
WSACleanup();
}
}

int soc_connect(struct test *test)
{
FD_ZERO(&test->read_set);
FD_ZERO(&test->write_set);

printf("Making cookie\n");

make_cookie(test->cookie);

printf("Success in Making cookie\n");

/* Create and connect the control channel */
if (test->ctrl_sck < 0)
{
test->ctrl_sck = netdial(test->settings->domain, Ptcp, test->bind_address, 0, test->server_hostname, test->server_port);
}

if (test->ctrl_sck < 0) {
i_errno = IECONNECT;
return -1;
}

FD_SET(test->ctrl_sck, &test->read_set);
return 0;
}

void make_cookie(char *cookie)
{
static int randomized = 0;
char hostname[500];
struct timeval tv;
char temp[1000];

if ( ! randomized )
srand((int) time(0) ^ getpid());

(void) gethostname(hostname, sizeof(hostname));
(void) gettimeofday(&tv, 0);
(void) snprintf(temp, sizeof(temp), "%s.%ld.%06ld.%08lx%08lx.%s", hostname, (unsigned long int) tv.tv_sec, (unsigned long int) tv.tv_usec, (unsigned long int) rand(), (unsigned long int) rand(), "1234567890123456789012345678901234567890");

memcpy(cookie, temp, 36);
cookie[36] = '\0';
}

int netdial(int domain, int proto, char *local, int local_port, char *server, int port)
{
struct addrinfo hints, *local_res = NULL, *server_res = NULL;
int s;

WSADATA wsaData;
int iResult;
INT iRetval;

char port_str[6];
snprintf(port_str, 6, "%d", port);

iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed: %d\n", iResult);
return -1;
}

if (local) {
memset(&hints, 0, sizeof(hints));
hints.ai_family = domain;
hints.ai_socktype = proto;
if (getaddrinfo(local, port_str, &hints, &local_res) != 0)
{
WSACleanup();
printf("Net dial : 0\n");
return -1;
}
}

ZeroMemory(&hints, sizeof(hints));
hints.ai_family = domain;
hints.ai_socktype = proto;
hints.ai_protocol = IPPROTO_TCP;
if (getaddrinfo(server, port_str, &hints, &server_res) != 0)
{
WSACleanup();
return -1;
}


s = socket(server_res->ai_family, server_res->ai_socktype, server_res->ai_protocol);
if (s == INVALID_SOCKET) {
if (local)
{
if (local_res != NULL)
freeaddrinfo(local_res);
}
freeaddrinfo(server_res);
WSACleanup();
return -1;
}

printf("Socket created\n");

if (local) {
if (local_port) {
printf("Net dial : 3\n");
struct sockaddr_in *lcladdr;
lcladdr = (struct sockaddr_in *)local_res->ai_addr;
lcladdr->sin_port = htons(local_port);
local_res->ai_addr = (struct sockaddr *)lcladdr;
}

if (bind(s, (struct sockaddr *) local_res->ai_addr, local_res->ai_addrlen) < 0) {
_close(s);
WSACleanup();
freeaddrinfo(local_res);
freeaddrinfo(server_res);
printf("Net dial : 4\n");
return -1;
}
freeaddrinfo(local_res);
}

iResult = connect(s, server_res->ai_addr, (int)server_res->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(s);
s = INVALID_SOCKET;
}

freeaddrinfo(server_res);

if (s == INVALID_SOCKET) {
WSACleanup();
return -1;
}

printf("Socket connected\n");

WSACleanup();
return s;
}

输出

Making cookie
Success in Making cookie
Socket created
Socket connected
Run client : success in making socket
The Winsock 2.2 dll was found okay
select_result errors : WSAENOTSOCK

我已经用谷歌搜索了这个问题并尝试了很多解决方案,但我找不到适合我的解决方案。请问有哪位可以帮忙吗?

最佳答案

functions are in different files, so i need to call WSAStartup multiple times

不,你不知道。这是你的捏造。您需要在进程开始时调用 WSAStartup() 一次,并在进程结束时调用 WSACleanup() 一次。

我无法想象你是如何或从哪里得到这个想法的,但它是错误的。 Winsock 既不知道也不关心您有多少个 .c 文件。

关于c - Windows C套接字: select() gives WSAENOTSOCK error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37612275/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com