我正在使用winsock连接到远程服务器。我在连接套接字方面取得了成功,但是当我尝试使用select获取套接字详细信息时,它表示套接字不存在( WSAENOTSOCK )。
N.B:我正在以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
我已经搜索了这个问题并尝试了很多解决方案,但我找不到我的解决方案。请一个人请帮帮忙。
答案 0 :(得分:3)
函数在不同的文件中,所以我需要多次调用WSAStartup
不,你没有。这是你的捏造。您需要在流程开始时调用WSAStartup()
一次,并在流程结束时调用WSACleanup()
一次。
我无法想象你是如何或在何处得到这个想法的,但这是错误的。 Winsock既不知道也不关心你有多少.c文件。