我有一个小型Web应用程序,它打开TCP套接字连接,发出命令,读取响应,然后关闭对特定REST端点的每个请求的连接.
我已经开始使用Apache JMeter对端点进行负载测试,并注意到在运行一段时间后,我开始看到"无法分配请求的地址"之类的错误,打开此连接的代码是:
def lookup(word: String): Option[String] = {
try {
val socket = new Socket(InetAddress.getByName("localhost"), 2222)
val out = new PrintStream(socket.getOutputStream)
val reader = new BufferedReader(new InputStreamReader(socket.getInputStream, "utf8"))
out.println("lookup " + word)
out.flush()
var curr = reader.readLine()
var response = ""
while (!curr.contains("SUCC") && !curr.contains("FAIL")) {
response += curr + "\n"
curr = reader.readLine()
}
socket.close()
curr match {
case code if code.contains(SUCCESS_CODE) => {
Some(response)
}
case _ => None
}
}
catch {
case e: Exception => …Run Code Online (Sandbox Code Playgroud) 我想知道,多个应用程序如何使用相同的网络端口.TCP协议1端口中的AFAIK被分配给1个套接字连接.那么,例如,多个互联网浏览器如何同时使用端口80/8080?我可以将多个套接字绑定到同一个端口吗?我怎么能用C++做到这一点?
我一直试图快速编写一个简单的TCP / IP服务器,但是我无法提出解决方案。我已经尝试过在这里和整个网络中进行搜索,但是找不到与我正在使用的最新Swift版本兼容的内容:
Apple Swift版本2.1(swiftlang-700.1.101.6 clang-700.1.76)
目标:x86_64-apple-darwin14.5.0
操作系统:
Mac OS X 10.10.5 Yosemitte
下面的代码已经基于此代码完成:带Swift的Socket Server示例
import Foundation
var sock_fd: Int32
var server_addr_size: Int
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if sock_fd == -1 {
print("Failure: creating socket")
exit(EXIT_FAILURE)
}
server_addr_size = sizeof(sockaddr_in)
var server_addr = NSMutableData(length: server_addr_size)!
memset(UnsafeMutablePointer<Void>(server_addr.mutableBytes), 0, server_addr_size)
var addr = UnsafeMutablePointer<sockaddr_in>(server_addr.mutableBytes)
addr.memory.sin_len = __uint8_t(server_addr_size)
addr.memory.sin_family = sa_family_t(AF_INET) // chooses IPv4
addr.memory.sin_port = 12321 // chooses the port
let bind_server = bind(sock_fd, UnsafePointer<sockaddr>(server_addr.mutableBytes), socklen_t(server_addr_size))
if bind_server == -1 …Run Code Online (Sandbox Code Playgroud) 我读过的文档std::net和MIO,我已经找到了一些方法,如set_nodelay和set_keepalive,但我还没有找到一种方法来设置像其他套接字选项SO_REUSEPORT和SO_REUSEADDR一个给定的插座上.我怎样才能做到这一点?
以下是我的测试夹具的精髓 -
SetUp()
{
g_listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
/* localhost is the server */
bind(g_listen_sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
listen(g_listen_sock, max_connections);
}
testcase()
{
hdl = accept(g_listen_sock, NULL, NULL);
-- send()/recv() data on the socket --
}
TearDown()
{
shutdown(g_listen_sock, SHUT_RDWR);
close(g_listen_sock);
g_listen_sock = INVALID_SOCKET;
}
Run Code Online (Sandbox Code Playgroud)
在应用程序的正常使用中,侦听套接字仅在应用程序的生命周期中绑定一次,但是测试设置会反复打开和关闭侦听套接字.测试用例的第一次迭代工作正常但后续迭代在使用errno == 98ie EADDRINUSE 的bind()调用时失败.
我该如何避免这种情况?理想情况下,该解决方案不需要我具有单独的代码测试版本,例如在测试时使用SO_REUSEADDR.
PS - 相同的代码在Windows上正常工作,在Linux上发生bind()失败.
我正在使用套接字和Java编写聊天程序,我必须指定服务器监听的端口.
这是我的问题:
我如何确定该端口始终是免费的?
如果另一个程序也在监听该端口是否重要?
如果端口必须是空闲的并且默认端口已被占用,我将如何通知客户端端口号的更改?
我应该这样做,以便服务器继续尝试绑定到一个新端口,递增端口号,直到找到一个空闲端口?
我开发了一个包含一个小型http服务器的应用程序.
我的应用程序是在启动时启动的.如果应用程序正常停止(etc/init.d/myappli stop),套接字将被关闭
close (socket_desc);
Run Code Online (Sandbox Code Playgroud)
但如果我用kill -9套接字杀死它将不会被关闭
http服务器代码:
void http_server_init(void)
{
struct sockaddr_in server;
int cr_port;
for(;;) {
cr_port = conf.port;
int i = (DEFAULT_PORT == cr_port)? 1 : 0;
//Create socket
cr_socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (cr_socket_desc == -1)
{
LOG (ERROR,"Could not open server socket, Error no is : %d, Error description is : %s", errno, strerror(errno));
sleep(1);
continue;
}
/* enable SO_REUSEADDR */
int reusaddr = 1;
if (setsockopt(cr_socket_desc, SOL_SOCKET, SO_REUSEADDR, &reusaddr, …Run Code Online (Sandbox Code Playgroud) 我有一些生成套接字绑定的 Java 代码。很难提供一个最小的示例,因为这是 Web 框架的一部分,但它在某些时候有效地执行了此检查。
private static boolean portInUse(int port) {
// try to bind to this port, if it succeeds the port is not in use
try (ServerSocket socket = new ServerSocket(port)) {
socket.setReuseAddress(true);
return false;
} catch (IOException e) {
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
我可以看到,如果我使用同一端口运行两个不同的 Java 进程,它们都会落入第一个条件并返回false,因此两者都能够绑定到同一端口。我已经阅读了一些相关的套接字问题和解释,例如 this,但它们似乎听起来像是我指定的选项不可能实现这一点。看看setReuseAddress它的实现似乎只SO_REUSEADDR在套接字上设置。
我可以看到一个进程最终有一个套接字,就像ServerSocket[addr=0.0.0.0/0.0.0.0,localport=56674]在调试器中一样。如果我运行类似的命令,sudo lsof -n -i | grep -e LISTEN -e ESTABLISHED | grep 56674我可以看到两个进程绑定到同一端口:
java 68863 natdempk 1256u IPv4 …Run Code Online (Sandbox Code Playgroud) 目前我们有一个以这种方式启动的 Jetty 7 服务器
//create a new server listening on the 80
Server server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setReuseAddress(false);
connector.setPort(80);
server.setConnectors(new Connector[]{connector});
...
server.start();
Run Code Online (Sandbox Code Playgroud)
当没有其他应用程序捕获 80 端口时,一切都很好。我还确保两个 Jetty 实例无法开始侦听同一端口,因为setReuseAddress.
然而,有一些其他应用程序开始侦听端口 80 并且 Jetty 服务器仍然设法启动(未能在那里提供连接)的情况。
C:\Users\bacadmin>netstat -anov | find ":80 "
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 3976
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 3808
TCP [::]:80 [::]:0 LISTENING 3976
Run Code Online (Sandbox Code Playgroud)
如果端口未打开,这怎么可能,以及如何确保 Jetty 在启动期间获得异常。
我试图编写一个基本的套接字应用程序,它将接受来自客户端的字符串,并对我在内存中的数据结构做一些工作.我正在尝试使用C++ 11,因为我希望语言支持多线程,我发现了一个奇怪的问题.我有代码在端口1234上创建一个侦听套接字,并接受一个连接,打印出一个虚拟字符串并关闭它.如果我编译它:
g++ -o socket_test socket_test.cpp
它工作得很好,但如果我用它编译它:
g++ -std=c++11 -o socket_test socket_test.cpp
它编译并运行良好,但如果我尝试连接到端口,它会在连接被拒绝时反弹.测试代码在这里:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
using namespace std;
int main()
{
cout << "Hello world, I'm going to open a socket on port 1234 now!" << endl;
int m_socket = 0;
int m_client = 0;
int port = 1234;
sockaddr_in serv_addr, client_addr;
socklen_t client_len;
m_socket = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr …Run Code Online (Sandbox Code Playgroud) 我正在使用 boost 1.75.0,我正在尝试更新我的服务器,以便他可以同时监听两个不同的端口,比如说IP 127.0.0.1 port 6500 and port 6600.
我需要保留Server两个套接字吗?这是我的服务器
#include <boost/asio/io_service.hpp>
#include <boost/asio.hpp>
#include <queue>
#include "Session.h"
using boost::asio::ip::tcp;
class Server
{
public:
Server(boost::asio::io_service &io_service, short port)
: acceptor_(io_service, tcp::endpoint(tcp::v4(), port)),
socket_(io_service)
{
do_accept();
}
private:
void do_accept(){
acceptor_.async_accept(socket_,
[this](boost::system::error_code ec) {
if (!ec) {
std::cout << "accept connection\n";
std::make_shared<Session>(std::move(socket_))->start();
}
do_accept();
});
}
tcp::acceptor acceptor_;
tcp::socket socket_;
};
Run Code Online (Sandbox Code Playgroud)
这是我的课程
#include <boost/asio/io_service.hpp>
#include <boost/asio.hpp>
#include "message.h"
#include <fstream>
#include <boost/bind/bind.hpp>
namespace {
using boost::asio::ip::tcp;
auto constexpr …Run Code Online (Sandbox Code Playgroud)