Python与C++(Winsock)的Socket编程对比
我有一个用Python写的程序,可以在互联网上聊天,运行得很好。但是我用C++写的类似程序却无法在互联网上工作。
Python程序如下:
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 个回答
1
根据文档,sendto
这个函数在成功时会返回一个大于0的数字(表示发送的字节数),而在失败时会返回一个小于0的数字。在失败的情况下,你可以使用WSAGetLastError来获取更多的信息。所以你可以尝试保存sendto
的结果,打印出来(同时也打印你想发送的数据的大小),如果出现错误的话,也把最后的错误代码打印出来。这样你就能看到什么情况了。