Немного исправил код, теперь данные всегда доходят, но ответ все равно неполный. Вот, собственно, код сервера: Code: #include <iostream> #include <winsock.h> using namespace std; SOCKET serv; SOCKET ClientSock; int main() { try { WSADATA wsa; if(WSAStartup(MAKEWORD(2,0), &wsa)) throw "Can't start WSA"; serv = socket(AF_INET, SOCK_STREAM, 0); if(serv == INVALID_SOCKET) throw "INVALID SOCKET serv"; struct sockaddr_in srv; srv.sin_addr.s_addr = INADDR_ANY; srv.sin_port = htons(4356); srv.sin_family = AF_INET; memset(&(srv.sin_zero), 0, 8); if(bind(serv, (sockaddr *)&srv, sizeof(srv))) throw "Can't bind socket"; if(listen(serv, 10)) throw "Can't listen socket"; struct sockaddr_in client_addr; memset(&(client_addr.sin_zero), 0, 8); char response[256]; char* answer = new char[256]; answer = "HelloFromServer"; int clientLen = sizeof(client_addr); if(ClientSock = accept(serv, (struct sockaddr *)&client_addr, &clientLen)) { cout << "New Client " << inet_ntoa(client_addr.sin_addr) <<endl; while (recv(ClientSock, response, sizeof(response)-1, 0)) { if(send(ClientSock, answer, sizeof(answer), 0) == SOCKET_ERROR) throw "Can't send data"; cout << response << endl; } delete(answer); closesocket(serv); closesocket(ClientSock); WSACleanup(); } } catch (const char* b) { closesocket(serv); closesocket(ClientSock); WSACleanup(); MessageBox(NULL, b, "Error", MB_OK); } return 0; } А тут код клиента: Code: #include <iostream> #include <winsock.h> using namespace std; SOCKET sock; int main() { try { WSAData wsa; if(WSAStartup(MAKEWORD(2,0), &wsa)) throw "Can't start WSA"; sock = socket(AF_INET, SOCK_STREAM, 0); if(sock == INVALID_SOCKET) throw "INVALID SOCKET sock"; struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(4356); memset(&(addr.sin_zero), 0, 8); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); char data[256]; char *response = new char[256]; if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) throw "Can't connect to server"; std::string checkEx; while(1) { cin >> data; checkEx = data; if(checkEx == "exit") throw "Exit"; if(send(sock, data, sizeof(data), 0) == SOCKET_ERROR) throw "Can't send data"; if(recv(sock, response, sizeof(response)-1, 0) == SOCKET_ERROR) throw "Can't recieve data"; cout << response << endl; } closesocket(sock); WSACleanup(); } catch (const char* b) { closesocket(sock); WSACleanup(); MessageBox(NULL, b, "Error", MB_OK); } return 0; } Проблема в том, что до сервера доходят данные только в первый раз. Клиенту же вместо "HellowFromServer" приходит "Hel". Больше данные до сервера не доходят.
Code: if(recv(sock, response, sizeof(response)-1, 0) == SOCKET_ERROR) throw "Can't recieve data"; Здесь ты пытаешься получить 3 байта данных от сервера. sizeof(response) возвращает размер типа char *, который равняется 4 и также ты еще отнимаешь 1. Вместо sizeof() используй strlen() из string.h.
Спасибо. Не стал strlen использовать, в сервере создал другую переменную char buf[256], в нее копирую, потом отправляю.
Да, нормально. Также немного поспешил, когда сказал, что в recv нужно использовать strlen() (она же возвратит не обязательно полный размер массива, а скорее даже наоборот). Лучше использовать константное значение для размера буфера, чтобы избавиться от "магических" чисел.
Теперь имеется возможность передачи файла, и каждый клиент обрабатывается в новом потоке, но почему то при подключении второго клиента, первому так и не приходит ответ от сервера. Сервер: Code: #include <iostream> #include <winsock.h> #include <windows.h> #include <fstream> using namespace std; DWORD WINAPI New_Client(LPVOID clien_socket); SOCKET serv; SOCKET ClientSock; int main() { try { WSADATA wsa; if(WSAStartup(MAKEWORD(2,0), &wsa)) throw "Can't start WSA"; serv = socket(AF_INET, SOCK_STREAM, 0); if(serv == INVALID_SOCKET) throw "INVALID SOCKET serv"; struct sockaddr_in srv; srv.sin_addr.s_addr = INADDR_ANY; srv.sin_port = htons(4356); srv.sin_family = AF_INET; memset(&(srv.sin_zero), 0, 8); if(bind(serv, (sockaddr *)&srv, sizeof(srv))) throw "Can't bind socket"; if(listen(serv, 10)) throw "Can't listen socket"; struct sockaddr_in client_addr; memset(&(client_addr.sin_zero), 0, 8); int clientLen = sizeof(client_addr); while (ClientSock = accept(serv, (struct sockaddr *)&client_addr, &clientLen)) { cout << "New Client " << inet_ntoa(client_addr.sin_addr) <<endl; DWORD thID; CreateThread(NULL, NULL, New_Client, &ClientSock, NULL, &thID); } closesocket(serv); closesocket(ClientSock); WSACleanup(); return 0; } catch (const char* b) { closesocket(serv); closesocket(ClientSock); WSACleanup(); MessageBox(NULL, b, "Server Error", MB_OK); } return 0; } DWORD WINAPI New_Client(LPVOID client_socket) { SOCKET my_sock = ((SOCKET *)client_socket)[0]; char response[256]; char BufForFile[1024]; FILE* f; std::string DataType; while(recv(my_sock, response, sizeof(response), 0)) { DataType = response; if(DataType == "FILE") { recv(my_sock, response, sizeof(response), 0); f = fopen(response, "w"); fclose(f); cout << "Recieving file " << response << endl; recv(my_sock, BufForFile, sizeof(BufForFile), 0); cout <<"Getting File : " << BufForFile << endl; std::ofstream ss; ss.open(response); ss << BufForFile; cout << "File getting success" << endl; } else if(DataType == "stop") { closesocket(my_sock); return 0; } else { if(send(ClientSock, response, sizeof(response), 0) == SOCKET_ERROR) throw "Can't send data"; cout << response << endl; } } return 0; } Клиент: Code: #include <iostream> #include <winsock.h> #include <fstream> using namespace std; SOCKET sock; void sendFile(char* fname) { char buf[1024]; FILE* f = fopen(fname, "r"); fread(buf, 1024, 1, f); cout << "Send file : " << buf << endl; fclose(f); char file[256] = "FILE"; char name[32]; strcpy(name, fname); send(sock, file, sizeof(file), 0); send(sock, name, sizeof(name), 0); send(sock, buf, sizeof(buf), 0); cout << "File Send Successfully" << endl; } int main() { try { WSAData wsa; if(WSAStartup(MAKEWORD(2,0), &wsa)) throw "Can't start WSA"; sock = socket(AF_INET, SOCK_STREAM, 0); if(sock == INVALID_SOCKET) throw "INVALID SOCKET sock"; struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(4356); memset(&(addr.sin_zero), 0, 8); char* ip = new char[8]; cout << "IP : "; cin >> ip; addr.sin_addr.s_addr = inet_addr(ip); char data[256]; char response[256]; if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) throw "Can't connect to server"; std::string checkEx; char* fname = new char[32]; while(1) { cin.getline(data, 256); checkEx = data; if(checkEx == "exit") throw "Exit"; if(checkEx == "file") { cout << "Name : "; cin.getline(fname, 32); cout << "Trying to send file..." << endl; sendFile(fname); continue; } if(send(sock, data, sizeof(data), 0) == SOCKET_ERROR) throw "Can't send data"; if(recv(sock, response, sizeof(response), 0) == SOCKET_ERROR) throw "Can't recieve data"; cout << response << endl; } closesocket(sock); WSACleanup(); catch (const char* b) { closesocket(sock); WSACleanup(); MessageBox(NULL, b, "Server Error", MB_OK); } return 0; } }
1) в коде сервера: Code: ... else { if(send(ClientSock /* my_sock */, response, sizeof(response), 0) == SOCKET_ERROR) ... 2) не везде проверяешь успешность отправки\приемки, не проверяешь сколь отправил и сколь принял байт, а только чекаешь на SOCKET_ERROR, чего не всегда достаточно, либо и того не делаешь 3) учитывай фрагментацию пакетов