ZBLOG

我在客户端如何指定端口取和服务端通信

在客户端进行通信时,通常不需要显式地指定一个特定的本地端口,因为操作系统会自动分配一个可用的端口来建立连接。但如果您确实想要指定客户端使用的本地端口,可以使用 bind() 函数在调用 connect() 之前绑定一个特定的本地地址和端口。

示例代码

下面是如何在客户端代码中指定本地端口与服务器通信的示例:

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <fcntl.h>
#include <arpa/inet.h>

int setNonBlocking(int sockfd) {
    int flags = fcntl(sockfd, F_GETFL, 0);
    if (flags == -1) {
        std::cerr << "Failed to get socket flags!" << std::endl;
        return -1;
    }

    if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
        std::cerr << "Failed to set non-blocking!" << std::endl;
        return -1;
    }
    
    return 0; // Success
}

void connectToPeer(const char* ip, int port, int localPort) {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        std::cerr << "Socket creation failed!" << std::endl;
        return;
    }

    struct sockaddr_in localAddr;
    memset(&localAddr, 0, sizeof(localAddr));
    localAddr.sin_family = AF_INET;
    localAddr.sin_port = htons(localPort); // 指定本地端口
    localAddr.sin_addr.s_addr = htonl(INADDR_ANY); // 使用任意可用地址

	// 在连接之前绑定本地地址和端口
	if (bind(sockfd, (struct sockaddr*)&localAddr, sizeof(localAddr)) == -1) {
		std::cerr << "Bind failed! Error: " << errno << std::endl;
		close(sockfd);
		return; 
	}

	struct sockaddr_in peerAddr;
	memset(&peerAddr, 0, sizeof(peerAddr));
	peerAddr.sin_family = AF_INET;
	peerAddr.sin_port = htons(port);
	
	if (inet_pton(AF_INET, ip, &peerAddr.sin_addr) <= 0) {
	    std::cerr << "Invalid address or address not supported" << std::endl;
	    close(sockfd);
	    return;
	}

	setNonBlocking(sockfd);

	if (connect(sockfd, (struct sockaddr*)&peerAddr, sizeof(peerAddr)) == -1) {
	    if (errno != EINPROGRESS) { // Check for error on connection
	        std::cerr << "Connection failed! Error: " << errno << std::endl; 
	        close(sockfd);
	        return; 
	    }
	}
	
	std::cout << "Connected successfully." << std::endl;

	close(sockfd); // Remember to close the socket when done.
}

int main() {
	const char* remoteIp = "192.168.8.36"; // Replace with the other client's IP address
	int remotePort = 5000; // The port you wish to connect to
	int localPort = 6000; // You want your client to use this specific port

	connectToPeer(remoteIp, remotePort, localPort);

	return 0;
}

注意事项

  1. 权限:请注意,如果你尝试绑定到小于1024的端口号,可能需要更高的权限(例如,超级用户权限)。因此,在实际应用中,尽量选择大于1024的端口。

  2. 并发连接:如果多个客户端尝试同时使用相同的本地端口,会导致“地址已在使用”的错误。因此,请确保在同一时间只有一个进程/线程绑定到该特定本地端口。

  3. 网络配置:确保防火墙设置不会阻止您选择的本地端口以及目标主机和目标端口之间的数据流。

通过以上方法,您可以成功指定并使用特定的本地端口与服务器进行通信。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=6412

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?