最近我正在制作能够连接多个客户端的多线程服务器应用程序。但是,当我运行客户端应用程序时,一些运行时库异常发生在" Debug Assertion Failed"对话。我无法找出此错误的确切原因。我在Visual Studio Ultimate 2013中使用了Winsock API。有人可以请我帮忙寻找解决方案吗?任何帮助将不胜感激!
客户端:
#include <windows.h>
#include <winsock.h>
#include <stdio.h>
#include <iostream>
#include <signal.h>
#include <stdio.h>
using namespace std;
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
//DECLARATIONS
//error trapping signals
#define SIGINT 2
#define SIGKILL 9
#define SIGQUIT 3
// SOCKETS
SOCKET sock, client;
void s_handle(int s)
{
if (sock)
closesocket(sock);
if (client)
closesocket(client);
WSACleanup();
Sleep(10);
cout << "EXIT SIGNAL :" << s;
exit(0);
}
void s_cl(char *a, int x)
{
cout << a;
s_handle(x + 1000);
}
int main()
{
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
//SetConsoleTitle(".:: Basic Echo Client By KOrUPt 07 ::. ");
//Declarations
DWORD poll;
int res, i = 1, port = 999;
char buf[100];
char msg[100] = "";
char ip[15];
WSADATA data;
signal(SIGINT, s_handle);
signal(SIGKILL, s_handle);
signal(SIGQUIT, s_handle);
cout << "\t\tEcho This is a Client";
cout << "\n\n\n\t\tEnter IP to connect to: ";
gets(ip);
sockaddr_in ser;
sockaddr addr;
ser.sin_family = AF_INET;
ser.sin_port = htons(123); //Set the port
ser.sin_addr.s_addr = inet_addr(ip); //Set the address we want to connect to
memcpy(&addr, &ser, sizeof(SOCKADDR_IN));
res = WSAStartup(MAKEWORD(1, 1), &data); //Start Winsock
cout << "\n\nWSAStartup"
<< "\nVersion: " << data.wVersion
<< "\nDescription: " << data.szDescription
<< "\nStatus: " << data.szSystemStatus << endl;
if (res != 0)
s_cl("WSAStarup failed", WSAGetLastError());
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //Create the socket
if (sock == INVALID_SOCKET)
s_cl("Invalid Socket ", WSAGetLastError());
else if (sock == SOCKET_ERROR)
s_cl("Socket Error)", WSAGetLastError());
else
cout << "Socket Established" << endl;
res = connect(sock, &addr, sizeof(addr)); //Connect to the server
if (res != 0)
{
s_cl("SERVER UNAVAILABLE", res);
}
else
{
cout << "\nConnected to Server: ";
memcpy(&ser, &addr, sizeof(SOCKADDR));
}
char RecvdData[100] = "";
int ret;
while (true)
{
strcpy(buf, "");
cout << "\nEnter message to send ->\n";
fgets(buf, sizeof(buf), stdin);
Sleep(5);
res = send(sock, buf, sizeof(buf), 0);
if (res == 0)
{
//0==other side terminated conn
printf("\nSERVER terminated connection\n");
Sleep(40);
closesocket(client);
client = 0;
break;
}
else if (res == SOCKET_ERROR)
{
//-1 == send error
printf("Socket error\n");
Sleep(40);
s_handle(res);
break;
}
ret = recv(sock, RecvdData, sizeof(RecvdData), 0);
if (ret > 0)
{
cout << endl << RecvdData;
strcpy(RecvdData, "");
}
}
closesocket(client);
WSACleanup();
}
服务器:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <winsock.h>
#include <iostream>
using namespace std;
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
// our thread for recving commands
DWORD WINAPI receive_cmds(LPVOID lpParam)
{
cout << "thread created\r\n";
// set our socket to the socket passed in as a parameter
SOCKET current_client = (SOCKET)lpParam;
// buffer to hold our recived data
char buf[100];
// buffer to hold our sent data
char sendData[100];
// for error checking
int res;
// our recv loop
while (true)
{
res = recv(current_client, buf, sizeof(buf), 0); // recv cmds
Sleep(2);
if (res == 0)
{
//MessageBox(0, "error", "error", MB_OK);
closesocket(current_client);
ExitThread(0);
}
if (strstr(buf, "hello"))
{ // greet this user
cout << "\nrecived hello cmd";
strcpy(sendData, "hello, greetings from server\n");
Sleep(2);
send(current_client, sendData, sizeof(sendData), 0);
}
else if (strstr(buf, "bye"))
{ // dissconnected this user
cout << "\nrecived bye cmd\n";
strcpy(sendData, "cya\n");
Sleep(2);
send(current_client, sendData, sizeof(sendData), 0);
// close the socket associted with this client and end this thread
closesocket(current_client);
ExitThread(0);
}
else
{
strcpy(sendData, "Invalid cmd\n");
Sleep(2);
send(current_client, sendData, sizeof(sendData), 0);
}
// clear buffers
strcpy(sendData, "");
strcpy(buf, "");
}
}
int main()
{
printf("Starting up multi-threaded TCP server");
// our masterSocket(socket that listens for connections)
SOCKET sock;
// for our thread
DWORD thread;
WSADATA wsaData;
sockaddr_in server;
// start winsock
int ret = WSAStartup(0x101, &wsaData); // use highest version of winsock avalible
if (ret != 0)
{
return 0;
}
// fill in winsock struct ...
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(123); // listen on telnet port 23
// create our socket
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
return 0;
}
// bind our socket to a port(port 123)
if (bind(sock, (sockaddr*)&server, sizeof(server)) != 0)
{
return 0;
}
// listen for a connection
if (listen(sock, 5) != 0)
{
return 0;
}
// socket that we sendrecv data on
SOCKET client;
sockaddr_in from;
int fromlen = sizeof(from);
// loop forever
while (true)
{
// accept connections
client = accept(sock, (struct sockaddr*)&from, &fromlen);
cout << "Client connected\r\n";
// create our recv_cmds thread and parse client socket as a parameter
CreateThread(NULL, 0, receive_cmds, (LPVOID)client, 0, &thread);
}
// shutdown winsock
closesocket(sock);
WSACleanup();
// exit
return 0;
}