标签: network-programming

在 C/Unix 中侦听 IP 子网的套接字

我正在尝试用 C 编写服务器-客户端套接字程序。目标是让服务器侦听特定端口,但跨越属于同一 IP 子网的 IP 地址范围。这个 IP 子网是127.xxx范围的一部分(当然不是 127.0.0.1)。

需要注意的几点:

  • 这是一个基于流的套接字,而不是数据报套接字。
  • 这不是广播地址。
  • 仅在 Unix/Linux 平台上用 C/C++ 实现

我不想为该范围内的每个 IP 地址在服务器上打开多个套接字。这是不可扩展的。

任何帮助将不胜感激。这甚至可行吗?

c c++ unix network-programming unix-socket

1
推荐指数
1
解决办法
2685
查看次数

NetworkStream 不支持搜索操作

我正在创建简单的代理服务器,但遇到了一个奇怪的情况,我有以下代码:

var clientRequestStream = _tcpClient.GetStream();
var requestHeader = clientRequestStream.GetUtf8String();
Run Code Online (Sandbox Code Playgroud)

GetUtf8StringStream读取流(包含HttpRequest标题)的类的扩展方法。我需要提取这些标头以访问主机和请求的 URL。完成读取 NetworkStream 后。我需要执行搜索操作并设置它,clientRequestStream.Position = 0;因为我必须读取该流并将其写入另一个远程NetworkStream.

我不知道我应该如何解决这个问题。任何建议都会有所帮助。


编辑:我也尝试将 NetworkStream 复制到 MemoryStream 然后对 MemoryStream 执行查找操作,没有例外,但是当我想从 NetworkStream 读取时,其缓冲区始终为空。

我也用反射器看看里面发生了什么Stream.CopyTo。见下面的代码:

    private void InternalCopyTo(Stream destination, int bufferSize)
    {
        int num;
        byte[] buffer = new byte[bufferSize];
        while ((num = this.Read(buffer, 0, buffer.Length)) != 0)
        {
            destination.Write(buffer, 0, num);
        }
    }
Run Code Online (Sandbox Code Playgroud)

这就是 CopyTo 所做的。即使我使用CopyTo问题仍然没有解决。因为它将源(此处为 NetworkStream)读取到最后。我有另一种方法来处理这种情况吗?

.net c# sockets network-programming tcpclient

1
推荐指数
1
解决办法
5559
查看次数

如何确定异步阻塞应用程序中的理想池大小?

这是有问题的代码(一个非常简单的爬虫),该文件是一个 url 列表,通常大于 1000。

import sys, gevent
from gevent import monkey
from gevent.pool import Pool
import httplib, socket
from urlparse import urlparse
from time import time

pool = Pool(100)

monkey.patch_all(thread=False)

count = 0
size = 0
failures = 0

global_timeout = 5
socket.setdefaulttimeout(global_timeout)

def process(ourl, mode = 'GET'):
    global size, failures, global_timeout, count
    try:
        url = urlparse(ourl)
        start = time()
        conn = httplib.HTTPConnection(url.netloc, timeout = global_timeout)
        conn.request(mode, ourl)
        res = conn.getresponse()
        req = res.read()
        end = time()
        bytes = len(req) …
Run Code Online (Sandbox Code Playgroud)

python io asynchronous network-programming gevent

1
推荐指数
1
解决办法
1609
查看次数

无需中央服务器的 P2P 握手

我编写了一个客户端-服务器应用程序,旨在通过局域网交换文件(除其他外)。在服务器模式下,应用程序侦听具有特定标识标头的 TCP 连接。在客户端模式下,它尝试与用户提供的 IP 地址建立 TCP 连接。

我现在需要调整这个应用程序以在互联网上工作。没有太多的网络编程经验,我不知道如何在没有某种中央服务器(用于宣布存在等)的情况下实现这一目标。这不是一个选项。

假设我的应用程序在家庭网络后面的机器上以服务器模式运行。您(读者)有客户端模式的应用程序,我们需要连接。我们都没有静态 IP 地址。客户端有没有办法到达服务器?服务器和客户端都可以找出他们的公共 IP 地址,但除此之外,我不知道该怎么做。

任何指导将不胜感激。

编辑:根据答案,需要进行一些澄清。我的问题不是关于发现。客户端和服务器都可以查询它们的公共地址,用户可以通过其他媒介交换这些 IP。问题是,一旦知道对方的 IP 但双方都在没有适当端口转发的网络后面,如何建立连接。例如,我的应用程序使用端口 51200 作为默认端口。

.net c# networking p2p network-programming

1
推荐指数
1
解决办法
2209
查看次数

如何将 HTTPS 流量从 SOCKS 代理转发到 HTTP 代理

我编写了一个 SOCKS 代理,如果链接关闭,它可以同时处理 HTTP 和 HTTPS 流量。

如果链接打开并且转发主机和端口属于过滤 HTTP 代理,则只有 HTTP 流量可以流动。HTTPS 流量不流动并报告 SSL 错误。

请注意,当请求直接来自浏览器而不是来自 SOCKS 服务器时,HTTP 代理会处理 HTTPS 流量。

例如,如果我向https://www.google.com发出请求,则会发生以下情况:

1) 客户端发送 SOCKS 5 问候,让我们知道哪些身份验证方法是可以接受的。

2) 服务器以 NO_AUTH 响应

3) 客户端发送连接请求(包括预期的目标主机和端口)。

4) 服务器创建一个套接字并将其连接到 HTTP 代理服务器,并以 GRANTED 响应客户端

5) SOCKS 服务器然后收到以下请求(隐形/控制字符已全部替换为其字符代码,因此您可以看到发生了什么):

\u0016\u0003\u0001\u0000Ñ\u0001\u0000\u0000Í\u0003\u0003áp¥@Ia¹\u0001„Ä\u0006 É;š‰‰4\u001dýà•J>Ü6¢Þ\fö\u001c%\u0000\u0000(À+À/\u0000žÌ\u0014Ì\u0013À\nÀ\tÀ\u0013À\u0014À\u0007À\u0011\u00003\u00002\u00009\u0000œ\u0000/\u00005\u0000\n\u0000\u0005\u0000\u0004\u0001\u0000\u0000|\u0000\u0000\u0000\u0013\u0000\u0011\u0000\u0000\u000ewww.google.comÿ\u0001\u0000\u0001\u0000\u0000\n\u0000\b\u0000\u0006\u0000\u0017\u0000\u0018\u0000\u0019\u0000\u000b\u0000\u0002\u0001\u0000\u0000#\u0000\u00003t\u0000\u0000\u0000\u0010\u0000\u001b\u0000\u0019\u0006spdy/3\bspdy/3.1\bhttp/1.1uP\u0000\u0000\u0000\u0005\u0000\u0005\u0001\u0000\u0000\u0000\u0000\u0000\u0012\u0000\u0000\u0000\r\u0000\u0012\u0000\u0010\u0004\u0001\u0005\u0001\u0002\u0001\u0004\u0003\u0005\u0003\u0002\u0003\u0004\u0002\u0002\u0002
Run Code Online (Sandbox Code Playgroud)

如您所见,它完全不可读,但我们已经从初始 SOCKS 连接消息(第 3 步)中知道用户打算去哪里,因此我们可以创建并发出以下连接请求:

CONNECT www.google.com:443 HTTP/1.1\r\nUser-Agent: MySocksServer\r\nProxy-Connection: keep-alive\r\nHost: www.google.com\r\n\r\n
Run Code Online (Sandbox Code Playgroud)

6) 这个新构造的 CONNECT 被发送到我们链接的 HTTP 代理,这个代理检查它的过滤规则并响应:

HTTP/1.1 200 Connection Established\r\nVia: 1.1 HTTPserverName\r\nX-WebMarshal-RequestID: AN_ID_STRING\r\n\r\n
Run Code Online (Sandbox Code Playgroud)

7) 这在我们的 SOCKS 服务器中接收并转发(未修改)到客户端。在我的调试中,我在发送请求之前直接监视套接字,并且可以看到客户端套接字已连接。

8) 引发的下一个事件是错误,错误为 SOCKET_NOT_CONNECTED,对套接字运行另一项检查确认客户端套接字确实不再连接。

为什么我的 Socket 会在第 …

sockets network-programming http network-protocols socks

1
推荐指数
1
解决办法
1万
查看次数

如何动态获取本地 IP 广播地址 C#

我的第一个问题是,C# UDP Chat 没有收到消息,试图解决这个问题是为了避免。

IPAddress.Broadcast
Run Code Online (Sandbox Code Playgroud)

所以我写了一个函数来确定本地广播:

    private IPAddress get_broadcast()
    {
        try
        {
            string ipadress;
            IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName()); // get a list of all local IPs
            IPAddress localIpAddress = ipHostInfo.AddressList[0]; // choose the first of the list
            ipadress = Convert.ToString(localIpAddress); // convert to string
            ipadress = ipadress.Substring(0, ipadress.LastIndexOf(".")+1); // cuts of the last octet of the given IP 
            ipadress += "255"; // adds 255 witch represents the local broadcast
            return IPAddress.Parse(ipadress); 
        }
        catch (Exception e)
        {
            errorHandler(e);
            return …
Run Code Online (Sandbox Code Playgroud)

c# network-programming broadcast

1
推荐指数
2
解决办法
8812
查看次数

通过套接字发送数据不起作用

我正在尝试通过套接字制作国际象棋游戏。有一个服务器负责将棋盘发送给玩家,以获取输入和响应等等。我试图创建一个客户端服务器(实际上是 2 个客户端和服务器),但它不起作用。客户端正确连接到服务器,但传递的数据不正确。例如,我从客户端发送“E2-C3”;recv 结果(在服务器端)始终为 0,否则会打印垃圾。

客户 :

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <sys/types.h>

// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")

using namespace std;


#define SERVER_IP "1.1.1.1"
#define SERVER_PORT 8888
#define BUFFER_SIZE 1024

// server side 
#define INVALID_MOVE 00
#define PLEASE_ENTER_A_MOVE 15
#define PRINT_BOARD 20
#define END_GAME 30

// client side
#define MOVE 10

int …
Run Code Online (Sandbox Code Playgroud)

c++ sockets networking network-programming client-server

1
推荐指数
1
解决办法
2035
查看次数

客户端中的 DatagramSocket 未绑定到服务器中的端口。端口已被使用

我有一个服务器正在等待客户端通过 DatagramSocket 发送数据包。但是当在客户端中我使用与服务器相同的端口时(以便它们可以通信)我在客户端得到一个异常:

Exception in thread "main" java.net.BindException: Address already in use: Cannot bind
at java.net.DualStackPlainDatagramSocketImpl.socketBind(Native Method)
at java.net.DualStackPlainDatagramSocketImpl.bind0(DualStackPlainDatagramSocketImpl.java:80)
at java.net.AbstractPlainDatagramSocketImpl.bind(AbstractPlainDatagramSocketImpl.java:93)
at java.net.DatagramSocket.bind(DatagramSocket.java:372)
at java.net.DatagramSocket.<init>(DatagramSocket.java:222)
at java.net.DatagramSocket.<init>(DatagramSocket.java:279)
at tp.Repositorio.main(Cliente.java:146)
Run Code Online (Sandbox Code Playgroud)

所以在服务器端,我有一个线程正在处理数据包。像这样的东西:

addr = InetAddress.getByName("localhost");
DatagramSocket socket = new DatagramSocket(5008, addr);
DatagramPacket packet = new DatagramPacket(buff, buff.length);
 while(true)
    {
      s.receive(packet);
// and then it throws another thread to treat the packet...
    }
Run Code Online (Sandbox Code Playgroud)

在客户端,我有这样的事情:

 InetAddress inet;
 inet = InetAddress.getByName("localhost");
 s_data = new DatagramSocket(5008, inet);
Run Code Online (Sandbox Code Playgroud)

我试图更改双方的端口,但它也给了我这个例外。如果我将端口更改为例如服务器中的 5003 和客户端中的 5004,它不会给我任何异常(当然)但它们无法相互连接。

你们有什么想法可以解决这个问题吗?

谢谢。

编辑:

这是以下客户端代码(称为 repositorio): …

java sockets networking network-programming bind

1
推荐指数
1
解决办法
6626
查看次数

套接字编程:connect() 因 IP 不存在而挂起

以下是创建套接字连接的代码,如果 IP 存在,则返回正套接字描述符,而如果 IP 不存在,则它会卡在例程中connect()

Connection::Connection(string& ip) : sock(0), status(0), conn(0){
    struct sockaddr_in sin;

    sock = socket(AF_INET, SOCK_STREAM, 0);//socket() returns -1 on failure.
    sin.sin_family = AF_INET;
    sin.sin_port = htons(22);
    sin.sin_addr.s_addr = inet_addr(ip.c_str());
    cout << "sock: " << sock << endl;
    //fcntl(sock, F_SETFL, O_NONBLOCK);
    if(sock != -1){
        conn = connect(sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in));
        cout << "conn: " << conn << endl;
        if ( conn != 0){
            status = -2;
        }
    }
    else{
        status = -1;
    }
}
Run Code Online (Sandbox Code Playgroud)

出于调试目的,我已将和放在 …

c++ sockets network-programming

1
推荐指数
1
解决办法
2838
查看次数

accept() 不断返回 0

这是一个简单的服务器,它只接受连接,然后打印套接字描述符。出于某种原因,每当我运行它时,我收到的唯一套接字描述符的值为 0。这甚至发生在多个客户端同时连接的情况下。我似乎误解了与 accept() 的行为有关的内容,或者我的代码中存在一些我无法找到的错误。这是代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

/* Utility for consisely killing the program. */
void abort_program(const char *error_message)
{
    fputs(error_message, stderr);
    exit(EXIT_FAILURE);
}

/* Establishes a passive listening port, returns socket descriptor. */
int setup_passive_port(int port)
{
    struct protoent *ptrp;  // pointer to a protocol table entry
    struct sockaddr_in sad; // structure to hold server's address
    int     sd;             // socket descriptor for listening

    /* Map TCP …
Run Code Online (Sandbox Code Playgroud)

c sockets network-programming server

1
推荐指数
1
解决办法
397
查看次数