2009-09-26 4 views
0

У меня есть программа python, которая отлично работает для интернет-чатов. Но программа, построенная на аналогичных сокетах на C++, не работает через Интернет.
программа PythonSocket program Python vs C++ (Winsock)

import thread 
import socket 


class p2p: 
    def __init__(self): 
     socket.setdefaulttimeout(50) 
     self.port = 3000 

     #Destination IP HERE 
     self.peerId = '59.95.18.156' 

     #declaring sender socket 
     self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM ) 
     self.socket.bind(('', self.port)) 
     self.socket.settimeout(50) 

     #starting thread for reception 
     thread.start_new_thread(self.receiveData,()) 

     while 1: 
      data=raw_input('>') 
      #print 'sending...'+data 
      self.sendData(data) 

    def receiveData(self): 
     while 1: 
      data,address=self.socket.recvfrom(1024) 
      print data 
    def sendData(self,data): 
     self.socket.sendto(data, (self.peerId,self.port)) 
if __name__=='__main__': 
    print 'Started......'  
    p2p() 

Я хочу построил подобную функциональность в C++. Я взял серверные и клиентские программы из MSDN. Но они работают только на локальном хосте не через интернет .. они являются ...

Sender

#include <stdio.h> 
#include "winsock2.h" 

void main() { 

    WSADATA wsaData; 
    SOCKET SendSocket; 
    sockaddr_in RecvAddr; 
    int Port = 3000; 
    char SendBuf[3]={'a','2','\0'}; 
    int BufLen = 3; 

    //--------------------------------------------- 
    // Initialize Winsock 
    WSAStartup(MAKEWORD(2,2), &wsaData); 

    //--------------------------------------------- 
    // Create a socket for sending data 
    SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 

    //--------------------------------------------- 
    // Set up the RecvAddr structure with the IP address of 
    // the receiver (in this example case "123.456.789.1") 
    // and the specified port number. 
    RecvAddr.sin_family = AF_INET; 
    RecvAddr.sin_port = htons(Port); 
    RecvAddr.sin_addr.s_addr = inet_addr("59.95.18.156"); 

    //--------------------------------------------- 
    // Send a datagram to the receiver 
    printf("Sending a datagram to the receiver...\n"); 
    sendto(SendSocket, 
    SendBuf, 
    BufLen, 
    0, 
    (SOCKADDR *) &RecvAddr, 
    sizeof(RecvAddr)); 

    //--------------------------------------------- 
    // When the application is finished sending, close the socket. 
    printf("Finished sending. Closing socket.\n"); 
    closesocket(SendSocket); 

    //--------------------------------------------- 
    // Clean up and quit. 
    printf("Exiting.\n"); 
    WSACleanup(); 
    return; 
} 

Приемник

#include <stdio.h> 
#include "winsock2.h" 
#include<iostream> 
using namespace std; 
void main() { 

    WSADATA wsaData; 
    SOCKET RecvSocket; 
    sockaddr_in RecvAddr; 
    int Port = 3000; 
    char RecvBuf[3]; 
    int BufLen = 3; 
    sockaddr_in SenderAddr; 
    int SenderAddrSize = sizeof(SenderAddr); 

    //----------------------------------------------- 
    // Initialize Winsock 
    WSAStartup(MAKEWORD(2,2), &wsaData); 

    //----------------------------------------------- 
    // Create a receiver socket to receive datagrams 
    RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 

    //----------------------------------------------- 
    // Bind the socket to any address and the specified port. 
    RecvAddr.sin_family = AF_INET; 
    RecvAddr.sin_port = htons(Port); 
    RecvAddr.sin_addr.s_addr = htonl(INADDR_ANY); 

    bind(RecvSocket, (SOCKADDR *) &RecvAddr, sizeof(RecvAddr)); 

    //----------------------------------------------- 
    // Call the recvfrom function to receive datagrams 
    // on the bound socket. 
    printf("Receiving datagrams...\n"); 
    while(true){ 
    recvfrom(RecvSocket, 
    RecvBuf, 
    BufLen, 
    0, 
    (SOCKADDR *)&SenderAddr, 
    &SenderAddrSize); 
    cout<<RecvBuf; 
    } 
    //----------------------------------------------- 
    // Close the socket when finished receiving datagrams 
    printf("Finished receiving. Closing socket.\n"); 
    closesocket(RecvSocket); 

    //----------------------------------------------- 
    // Clean up and exit. 
    printf("Exiting.\n"); 
    WSACleanup(); 
    return; 
} 

Большое спасибо за любую помощь ..

Извините за слишком много кода в вопросе.

ответ

1

Per the docs, sendto возвращает число, которое> 0 (количество переданных байтов) для достижения успеха, < 0 за неудачи, и в последнем случае используется WSAGetLastError для получения дополнительной информации. Поэтому попробуйте сохранить результат sendto, распечатав его (а также размер данных, которые вы пытаетесь отправить), а в случае ошибки также напечатайте код последней ошибки. Что вы видите тогда?