2009-09-26 62 views
0

我有python程序,它完美地用于网络聊天。但是用C++编写的类似套接字的程序不能通过互联网工作。
Python程序套接字程序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服务器和客户端程序。但他们只在本地主机不能通过互联网,有如下几点

#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

the docssendto返回一个数字,就是> 0(发送字节数)成功,< 0失败,而在后一种情况下,你使用WSAGetLastError以获取更多信息。因此,请尝试保存sendto结果,打印它(以及您尝试发送的数据的大小),并在发生错误时也打印最后一个错误代码。那么你看到了什么?