매우 간단하게 작동하는 매우 다른 recvfrom()
명령이 있습니다. "다른"스레드에서 호출되지 않는 한 그렇습니다.멀티 스레드 일 때 소켓이 작동하지 않는 이유는 무엇입니까?
더 많은 코드를 게시 할 예정이지만 관련 정보를 필터링 할 수 있습니다. 먼저 글로벌 변수 SOCKET Socket=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
이 있습니다.
너무 오래 스레드가 관여하지 않습니다,이 잘 작동 :
지금은 다음과 같이 스레드 뒤에 동일한 코드를 불렀다char message[_max_message_];
struct sockaddr_in* from;
int r;
int SenderAddrSize = sizeof (struct sockaddr);
r=recvfrom(Socket,message,_max_message_,0,(struct sockaddr *)&from,&SenderAddrSize);
printf("Bytes recieved: %i\nError Code: %i\n",r,WSAGetLastError);
: (. 코드는 기본적으로 &socket
을 무시) 이 pthread_create(&listener, NULL, listenloop, &Socket);
호출 대상 스레드에서 실행될 첫 번째 recvfrom()
은 -1을 반환하지만 "원본"스레드 (네트워킹이 설정된 곳)에서 recvfrom()
을 반환합니다. up)은 message
을 성공적으로 서버의 메시지로 채 웁니다.
제가 뭘 잘못하고 있는지 말해 주시겠습니까?
편집 : 나를 돕기에 충분히 친절한 낯선 사람들에게 12 줄 넘는 줄을 던지기는하지만, 그렇지 않으면 대답을 얻지 못할 것이라고 생각합니다. 여기 키트와 카 들레가 약간 수정되었습니다 :
#include <iostream>
//#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <conio.h>
using namespace std;
#include <string>
//One thread shall listen continually for responses from the server.
/*The other thread shall listen continually for user input, and fire off user input at the local
client to the server...*/
//#ifdef _WINDOWS
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
SOCKET Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
inline int randport()
{
return (50000 % rand() + 1000);
}
#define _serverip_ "***.***.***.***"
#define _welcome_ "Welcome,Wagon!"
#define _randomport_ 64000%rand()+100
#define _max_message_ 100
void *listenloop(void *arg)
{
//SOCKET* listener = (SOCKET)arg;
WSADATA WsaDat;
WSAStartup(MAKEWORD(2, 0), &WsaDat);
char message[_max_message_];
//SOCKET listener=(SOCKET)arg;
int r;
//sockaddr_in SenderAddr;
struct sockaddr_in from;
//while (1){
int SenderAddrSize = sizeof(struct sockaddr);
r = recvfrom(Socket, message, _max_message_, 0, (struct sockaddr *) &from,
&SenderAddrSize);
printf("Thread Bytes recieved: %i\nThread Error Code: %i\n", r,
WSAGetLastError);
return NULL ;
//}
return NULL ;
}
int main()
{
string user, pass, login;
WSADATA WsaDat;
WSAStartup(MAKEWORD(2, 0), &WsaDat);
int port;
cout << "Welcome!"
SOCKET Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
fflush(stdin); //As long as we compile with GCC Behavoir should be consistant
//TRY NOT TO SEND PLAINTEXT PASSWORDS LIKE THIS! IT MAY MAKE YOUR USERS VULNERABLE! DONE FOR SAKE OF SIMPLICITY HERE!
cout << "\n\nPlease enter the username you registered with:";
getline(cin, user);
cout << "\nPlease enter your password, my good sir: ";
getline(cin, pass);
struct hostent *host;
host = gethostbyaddr(_serverip_, strlen(_serverip_), AF_INET);
if (host == NULL)
{
cout << "\n\n UNABLE TO CONNECT TO SERVER. QUITTING. ";
return -1;
}
short errorcount = 3;
int socketfeedback;
///Put the address for the server on the "evelope"
SOCKADDR_IN SockAddr;
SockAddr.sin_port = htons(port);
SockAddr.sin_family = AF_INET;
SockAddr.sin_addr.s_addr = inet_addr(_serverip_);
///Sign the letter...
int myport = _randomport_;
int code;
SOCKADDR_IN service;
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr("localhost");
service.sin_port = htons(myport);
//bind(Socket, (SOCKADDR *) &service, sizeof(service));
//Start a thread, listening for that server
while ((errorcount))
{
code = bind(Socket, (SOCKADDR *) &service, sizeof(service));
if (code)
break;
else
return -5;
errorcount--;
myport = _randomport_;
service.sin_port = htons(myport);
}
login = user + ',' + pass;
if (!errorcount)
{
cout << "\n\nMiserable failure. Last Known Error Code: " << code;
return -1;
}
///Begin the listen loop!!
pthread_t listener;
pthread_create(&listener, NULL, listenloop, &Socket);
struct sockaddr result;
sendto(Socket, login.c_str(), strlen(login.c_str()), 0,
(struct sockaddr *) &SockAddr, sizeof(SockAddr));
char message[_max_message_];
//SOCKET listener=(SOCKET)arg;
//sockaddr_in SenderAddr;
struct sockaddr_in from;
int r;
int SenderAddrSize = sizeof(struct sockaddr);
r = recvfrom(Socket, message, _max_message_, 0, (struct sockaddr *) &from,
&SenderAddrSize);
printf("Bytes recieved: %i\nError Code: %i\n", r, WSAGetLastError);
//SOCKET listener=(SOCKET)arg;
WSACleanup();
return 0;
}
반환 값 -1과 관련된'errno'는 무엇입니까? 이런 일이 생길 때'perror'라고 부르십시오. 나는, 감사합니다 ... – EJP
는 WSAgetlast 오류에 따르면 ... 그것은 매우 큰 숫자이지만, 작업 및 휴무'recvfrom' 년대 모두 같은 수의, 그래서 나는 그것이 어떤 종류의 단지 유물라고 생각 했어요 '는 WINSOCK이 수 – user1833028
http://tangentsoft.net/wskfaq/articles/bsd-compatibility.html perror는 시도 할 것이다 ** 매우 ** 재미있을 것입니다. 그걸 우리 한테 보여줄 수 있니? – user1833028