套接字异常 windows。读取访问冲突
Exception with socket windows. Read access violation
只是想用 winsock 打开一个套接字。我从 visual studio 收到一条错误消息,指出我在 ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
上存在读取访问冲突
我的全部代码都在那里:
ListenSocket = INVALID_SOCKET;
ClientSocket = INVALID_SOCKET;
WORD wVersionRequested;
WSADATA wsaData;
int wsaerr;
wVersionRequested = MAKEWORD(2, 2);
wsaerr = WSAStartup(wVersionRequested, &wsaData);
if (wsaerr != 0)
{
printf("Server: The Winsock dll not found!\n");
WSACleanup();
return 0;
}
else
{
printf("Server: The Winsock2 dll found \n");
}
/* SOCKET is simply a UINT, created because
on Unix sockets are file descriptors(UINT) but not in windows
so new type SOCKET was created */
cout << AF_INET << endl ;
cout << SOCK_STREAM << endl ;
cout << IPPROTO_TCP << endl ;
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(ListenSocket == INVALID_SOCKET)
{
cerr << "Server: Error initializing socket!n" << endl;
WSACleanup();
return 0;
}
/* The SOCKADDR_IN structure is used by
Win Sockets to specify an endpoint address
to which the socket connects */
sockaddr_in service,client ;
service.sin_family = AF_INET;
service.sin_port = htons(port);
service.sin_addr.s_addr = INADDR_ANY;
/* bind just links the socket
with the sockaddr_in struct we initialized */
if(bind(ListenSocket,(SOCKADDR*)&service,sizeof(service))==SOCKET_ERROR)
{
printf("Server: Error binding socket to port \n");
WSACleanup();
return 0;
}
/* wait for incoming connections */
if(listen(ListenSocket,10)==SOCKET_ERROR)
printf("listen(): Error listening on socket %d\n", WSAGetLastError());
else
{
printf("Server: Waiting for connections...\n");
}
/* accept connections */
printf("Server: Waiting for a client to connect...\n");
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
wprintf(L"accept failed with error: %ld\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
} else {
wprintf(L"Client connected.\n");
acceptConns();
}
很想得到一些帮助,因为我不知道为什么它不起作用。
提前致谢
编辑:我正在使用以下代码在线程中创建该服务器。看来这就是我首先收到错误的原因
DWORD WINAPI myThread(LPVOID lpParameter)
{
tcp_server* server = (tcp_server*)lpParameter ;
server->start_listening(); // The above function
return 0 ;
}
.....
HANDLE myHandle = CreateThread(0, 0, myThread, server, 0,NULL);
I have a read access violation on ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
该行没有发生明显的读取访问。
但是,由于您显示的代码(出于诊断目的不完整)位于 class 方法 tcp_server::start_listening()
内,并且 ListenSocket
可能是该 class,并且您通过传递给线程的 tcp_server
对象指针调用 start_listening()
,按理说
唯一可能发生的读取是在分配给 ListenSocket
成员时访问隐式 this
指针。
当线程调用 start_listening()
时,最有可能指向的 tcp_server
对象在内存中无效(或者,至少当 socket()
是被调用,因为你事先初始化了 ListenSocket
)。如果那是真的,分配给 ListenSocket
将是 未定义的行为 ,这 可以 导致访问冲突错误(在其他类型的错误中,如果有的话)。
但是,您没有说明在调用 CreateThread()
之前如何创建 server
对象,或者在 CreateThread()
退出后如何处理对象,所以这个推理只是一个(有根据的)猜测,除非你展示一个更完整的代码示例。
只是想用 winsock 打开一个套接字。我从 visual studio 收到一条错误消息,指出我在 ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
我的全部代码都在那里:
ListenSocket = INVALID_SOCKET;
ClientSocket = INVALID_SOCKET;
WORD wVersionRequested;
WSADATA wsaData;
int wsaerr;
wVersionRequested = MAKEWORD(2, 2);
wsaerr = WSAStartup(wVersionRequested, &wsaData);
if (wsaerr != 0)
{
printf("Server: The Winsock dll not found!\n");
WSACleanup();
return 0;
}
else
{
printf("Server: The Winsock2 dll found \n");
}
/* SOCKET is simply a UINT, created because
on Unix sockets are file descriptors(UINT) but not in windows
so new type SOCKET was created */
cout << AF_INET << endl ;
cout << SOCK_STREAM << endl ;
cout << IPPROTO_TCP << endl ;
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(ListenSocket == INVALID_SOCKET)
{
cerr << "Server: Error initializing socket!n" << endl;
WSACleanup();
return 0;
}
/* The SOCKADDR_IN structure is used by
Win Sockets to specify an endpoint address
to which the socket connects */
sockaddr_in service,client ;
service.sin_family = AF_INET;
service.sin_port = htons(port);
service.sin_addr.s_addr = INADDR_ANY;
/* bind just links the socket
with the sockaddr_in struct we initialized */
if(bind(ListenSocket,(SOCKADDR*)&service,sizeof(service))==SOCKET_ERROR)
{
printf("Server: Error binding socket to port \n");
WSACleanup();
return 0;
}
/* wait for incoming connections */
if(listen(ListenSocket,10)==SOCKET_ERROR)
printf("listen(): Error listening on socket %d\n", WSAGetLastError());
else
{
printf("Server: Waiting for connections...\n");
}
/* accept connections */
printf("Server: Waiting for a client to connect...\n");
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
wprintf(L"accept failed with error: %ld\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
} else {
wprintf(L"Client connected.\n");
acceptConns();
}
很想得到一些帮助,因为我不知道为什么它不起作用。
提前致谢
编辑:我正在使用以下代码在线程中创建该服务器。看来这就是我首先收到错误的原因
DWORD WINAPI myThread(LPVOID lpParameter)
{
tcp_server* server = (tcp_server*)lpParameter ;
server->start_listening(); // The above function
return 0 ;
}
.....
HANDLE myHandle = CreateThread(0, 0, myThread, server, 0,NULL);
I have a read access violation on
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
该行没有发生明显的读取访问。
但是,由于您显示的代码(出于诊断目的不完整)位于 class 方法 tcp_server::start_listening()
内,并且 ListenSocket
可能是该 class,并且您通过传递给线程的 tcp_server
对象指针调用 start_listening()
,按理说
唯一可能发生的读取是在分配给
ListenSocket
成员时访问隐式this
指针。当线程调用
start_listening()
时,最有可能指向的tcp_server
对象在内存中无效(或者,至少当socket()
是被调用,因为你事先初始化了ListenSocket
)。如果那是真的,分配给ListenSocket
将是 未定义的行为 ,这 可以 导致访问冲突错误(在其他类型的错误中,如果有的话)。
但是,您没有说明在调用 CreateThread()
之前如何创建 server
对象,或者在 CreateThread()
退出后如何处理对象,所以这个推理只是一个(有根据的)猜测,除非你展示一个更完整的代码示例。