套接字程序 Python vs C++ (Winsock)

Posted

技术标签:

【中文标题】套接字程序 Python vs C++ (Winsock)【英文标题】:Socket program Python vs C++ (Winsock) 【发布时间】:2009-09-26 12:17:37 【问题描述】:

我有一个非常适合网络聊天的 python 程序。但是在 C++ 中基于类似套接字构建的程序无法在 Internet 上运行。 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】:

根据the docs,sendto 返回一个数字,>0(发送的字节数)表示成功,WSAGetLastError 获取更多信息。所以尝试保存sendto 结果,打印它(以及您尝试发送的数据的大小),并在出错的情况下打印最后一个错误代码。那你看到了什么?

【讨论】:

以上是关于套接字程序 Python vs C++ (Winsock)的主要内容,如果未能解决你的问题,请参考以下文章

Python 3套接字客户端发送数据和C++套接字服务器接收偏移数据?

将数据从 Python 程序发送到 C++ 程序的策略

C++ Openssl AES GCM 128bits代码示例,可wins10的visual studio 2017 中直接运行

在 C++ VS2015 中嵌入 Python

Python vs C++ Tensorflow 推理

来回 unix 域套接字锁