C++로 프로그래밍중인 소켓 응용 프로그램에 문제가 있습니다. Windows XP에서 Bloodshed Dev-Cpp로 프로그래밍하고 있습니다. 모든 메시지 전송을 처리하기위한 클래스를 만들었고 클라이언트와 서버 프로그램 모두에서 해당 클래스를 사용하여 서비스를 처리했습니다. 응용 프로그램 자체는 매우 기본적인 것입니다.이 모든 작업을 수행하는 것이 유일한 목적입니다.winsock recv() 및 accept() 문제
메시지를 보내는 클라이언트는 예상대로 작동합니다. 내 서버가 실행 중이면 메시지를 보낼 때 오류가 발생하지 않습니다. 실행 중이 아니면 오류가 발생합니다. 그러나 제 서버는 계속 이상한 횡설수설을 받아들입니다. 항상 같은 데이터입니다. 메시지를 받으면 효과가 없습니다. 내 고객이 서버를 식별하려고하면 다시 횡설수설합니다.
여기에 내 소스 코드가 포함되었습니다. 링커는 또한 두 개의 추가 매개 변수를 제공합니다. -lwsock32 및 Dev-Cpp와 함께 제공되는 libws2_32.a 라이브러리 포함.
여기 내 멧세이 클래스의 헤더입니다 : 정말 감사하겠습니다에 갈 수있는 일에 대해
#include "Messager.h"
#include <winsock2.h>
#include <sys/types.h>
#include <ws2tcpip.h>
#include <windows.h>
void Messager::init(void){
WSADATA wsaData;
WSAStartup(MAKEWORD(1,1), &wsaData);
}
bool Messager::connect(std::string ip, std::string port){
struct addrinfo hints;
struct addrinfo *res;
bool success = false;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
getaddrinfo(ip.c_str(), port.c_str(), &hints, &res);
sendSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
success = ::connect(sendSocket, res->ai_addr, res->ai_addrlen) != -1;
freeaddrinfo(res);
return success;
}
bool Messager::bind(std::string port){
struct addrinfo hints, *res;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
getaddrinfo(NULL, port.c_str(), &hints, &res);
listenSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if(listenSocket == INVALID_SOCKET){
return false;
}
if(::bind(listenSocket, res->ai_addr, res->ai_addrlen) == -1){
return false;
}
return true;
}
void Messager::listen(void){
::listen(listenSocket, 10);
}
int Messager::send(std::string message){
const std::string terminator = "\r\n";
std::string realMessage;
int size = 0;
int totalSent = 0;
realMessage = message;
realMessage += terminator;
size = realMessage.size();
totalSent = ::send(sendSocket, realMessage.c_str(), size, 0);
if(totalSent == 0 || totalSent == -1){
return 0; // There must be an error, 0 means it is an error
}
// This statement keeps adding the results of ::send to totalSent until it's the size of the full message
for(totalSent = 0; totalSent < size; totalSent += ::send(sendSocket, realMessage.c_str(), size, 0));
return totalSent;
}
// This function has been updated a lot thanks to @Luke
std::string Messager::receive(void){
const int bufferSize = 256;
const std::string terminator = "\r\n";
char buffer[bufferSize];
int i = 0;
int received = 0;
std::string tempString;
size_t term = 0;
for(i = 0; i < bufferSize; i++){
buffer[i] = 0;
}
received = ::recv(listenSocket, buffer, bufferSize, 0);
tempString = buffer;
term = tempString.find(terminator);
if(term != -1){ // Already have line
line = tempString;
}
while(received != -1 && received != 0){ // While it is receiving information...
// Flush the buffer
for(i = 0; i < bufferSize; i++){
buffer[i] = 0;
}
::recv(listenSocket, buffer, bufferSize, 0);
tempString += buffer;
term = tempString.find(terminator);
if(term != -1){ // Found terminator!
return tempString;
}
}
throw 0; // Didn't receive any information. Throw an error
}
어떤 아이디어 :
#ifndef MESSAGER
#define MESSAGER
#include <string>
class Messager{
private:
int sendSocket;
int listenSocket;
public:
void init(void);
bool connect(std::string ip, std::string port);
bool bind(std::string port);
void listen(void);
void send(std::string message);
std::string receive(void);
};
#endif
이들은 멧세이 클래스에 대한 내 정의입니다. 나는 코드를 서버와 클라이언트 사용을 게시 할 수 있습니다,하지만 난 일반적인 개요 제공 할 수 있습니다 필요한 경우 :
서버 :
- messager.init()
- messager.bind()
- 멧세이을 들어 봐요()
- messager.receive() <는 -) (수용 포함
클라이언트 :
- messager.init()
- messager.connect()
- messager.send() 사전에
감사합니다.
내가 그것에 대해 걱정했다. 나는 버퍼 룸을주기 위해 100 개 정도의 요소를 배열하려고 시도했지만 문제는 남아 있습니다. 다시 테스트하고 코드를 편집하여 문제의 일부가 아닌지 확인합니다. – rovaughn
방금 테스트를했는데 동일한 결과가 나타났습니다. 나는 그것을 안전하게 배열로 유지할 것이다. 의견을 보내 주셔서 감사합니다. – rovaughn
함수 배열을 벗어나지 못하기 때문에 char 배열로 만들 수 없습니다. 함수가 끝나고 반환 한 포인터가 쓰레기를 가리키면 파기됩니다. 데이터 영역을 malloc해야합니다. – paxdiablo