Ich mache eine Winsock-Anwendung, und etwas schlägt auf dem Server fehl, wenn es versucht, die Shutdown-Funktion zu machen. Das Projekt wird erstellt und ausgeführt, aber wenn die erste Verbindung des Clients eintrifft, nimmt es es und schlägt fehl in der Befehlszeile: "shutdown failed with error: 10038". Ich habe über den Fehler gelesen und es wird gesagt, dass es in der Regel ist, weil die Funktion Herunterfahren auf etwas angewendet wird, das kein SOCKET oder so ist. Aber beim Debuggen habe ich gesehen, dass es anscheinend ein Socket ist, also weiß ich nicht, was ich tun soll.Herunterfahren fehlgeschlagen mit Fehler 10038
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include "stdafx.h"
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
//Function declaration
const std::string currentDateTime();
int __cdecl NewClient(SOCKET ListenSocket, SOCKET ClientSocket, char *recvbuf, int recvbuflen, int iSendResult, int iResult);
std::string CommandGet(char *recvbuf);
void Login(char *recvbuf);
void print_data(char *recvbuf);
string GetUsername(char *recvbuf);
string GetThirdToken(char *recvbuf);
//Map & Struct creation
struct message{
static unsigned int last_id;
unsigned int id;
std::string baa;
std::string timestamp;
message(){};
message(const std::string& recvbuf_baa,const std::string& a_timestamp) :
baa(recvbuf_baa), timestamp(a_timestamp), id(++last_id)
{
}
};
map<std::string,std::vector<message *> > data;
map<std::string,std::vector<string> > followers;
//Global variables
unsigned int message::last_id = 0;
map<std::string,bool> loggedin;
int __cdecl main(void)
{
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult=0;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
while(true){
// Resolve the server address and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// Setup the TCP listening socket
iResult = ::bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// No longer need server socket
closesocket(ListenSocket);
return NewClient(ListenSocket, ClientSocket, recvbuf, recvbuflen, iSendResult, iResult);
}
}
int __cdecl NewClient(SOCKET ListenSocket, SOCKET ClientSocket, char *recvbuf, int recvbuflen, int iSendResult, int iResult){
// Receive until the peer shuts down the connection
do {
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0) {
printf("Bytes received: %d\n", iResult);
std::string cmd=CommandGet(recvbuf);
if (cmd=="log"){
std::string usrn=GetUsername(recvbuf);
std::string recvbuf_str="";
for(auto it=loggedin.begin();it!=loggedin.end();it++){
if ((*it).first==usrn){
recvbuf_str="loggedin";
if ((*it).second){
recvbuf_str="cantlogin";
break;
}
else{
loggedin[usrn]=1;
break;
}
break;
}
}
if (recvbuf_str==""){
recvbuf_str="newlogin";
Login(recvbuf);
}
iSendResult = send(ClientSocket, recvbuf_str.c_str(), iResult, 0);
if (iSendResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
}
}
else if (iResult == 0){
printf("Connection closing...\n");
closesocket(ClientSocket);}
else {
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
} while (iResult > 0);
// shutdown the connection since we're done
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ClientSocket);
WSACleanup();
return 0;
}
const std::string currentDateTime() {
time_t now = time(0);
struct tm tstruct;
char buf[80];
localtime_s(&tstruct, &now);
strftime(buf, sizeof(buf), "%Y-%m-%d %X", &tstruct);
return buf;
}
void Login(char *recvbuf){
std::string usrn= GetUsername(recvbuf);
std::vector<message *> messages;
data[usrn]=messages;
std::vector<string> follow;
followers[usrn]=follow;
loggedin[usrn]=1;
}
void print_data(char *recvbuf){
std::string usrn= GetUsername(recvbuf);
for(auto mapIt = data.cbegin(); mapIt != data.cend(); ++mapIt)
{
std::cout << "printing data for " << mapIt->first << ":" << std::endl;
for(auto vectIter = mapIt->second.cbegin(); vectIter != mapIt->second.cend(); ++vectIter)
{
std::cout << (*vectIter)->baa << ", " << (*vectIter)->timestamp << ", "
<< (*vectIter)->id << std::endl;
}
}
}
void print_followers(char *recvbuf){
std::string usrn= GetUsername(recvbuf);
for(auto mapIt = followers.cbegin(); mapIt != followers.cend(); ++mapIt)
{
std::cout << "printing followers for " << mapIt->first << ":" << std::endl;
for(auto vectIter = mapIt->second.cbegin(); vectIter != mapIt->second.cend(); ++vectIter)
{
std::cout << (*vectIter) << endl;
}
}
}
std::string CommandGet(char *recvbuf){
int start0=0;
std::string recvbuf_cmd;
std::string recvstr(recvbuf);
start0=recvstr.find(';');
recvbuf_cmd=recvstr.substr(0,start0);
return recvbuf_cmd;
}
string GetUsername(char *recvbuf){
int start0=0, start1=0;
std::string recvbuf_usrn;
std::string recvstr(recvbuf);
start0=recvstr.find(';');
start1=recvstr.find(';',start0+1);
recvbuf_usrn=recvstr.substr(start0+1,start1-start0-1);
return recvbuf_usrn;
}
string GetThirdToken(char *recvbuf){
int start0=0, start1=0, start2=0;
std::string recvbuf_thirdtoken;
std::string recvstr(recvbuf);
start0=recvstr.find(';');
start1=recvstr.find(';',start0+1);
start2=recvstr.find(';',start1+1);
recvbuf_thirdtoken=recvstr.substr(start1+1,start2-start1-1);
return recvbuf_thirdtoken;
}
ich laden das gesamte Projekt, falls Sie es überprüfen wollen tiefer (https://mega.nz/#!dtcx1DCL!dKWV2ryDDfiXv5H3Mi2p4PrBpie2CGrGJOTAwvQAV8M), aber das Problem in dem Server befindet (was ich den Code vereinfacht), ist der Kunde nur so können Sie die conection starten Geben Sie den Benutzernamen ein (aber kümmern Sie sich nicht darum).
Vielen Dank im Voraus, jede Hilfe wird geschätzt.
Geben Sie uns nicht "das ganze Projekt", vor allem als ein Link, der schal werden kann und die ganze Frage wertlos macht. Versuchen Sie stattdessen, ein [minimales, vollständiges und überprüfbares Beispiel] (http://stackoverflow.com/help/mcve) zu erstellen, um uns * im Fragenhauptteil * anzuzeigen. und wenn Sie Probleme haben, dann extrahieren Sie die relevanten Teile aus dem tatsächlichen Code und zeigen Sie uns, * auch * im Körper der Frage. Und wenn Sie dies noch nicht getan haben, lesen Sie bitte [wie Sie gute Fragen stellen können] (http://stackoverflow.com/help/how-to-ask). –
@JoachimPileborg danke für deine Antwort, ich habe die Frage bearbeitet, um den Servercode direkt in der Frage anzugeben. – 19mike95