我是关于在linux上构建一个服务器(我选择编程语言),它接受来自桌面软件的许多TCP/IP套接字持久连接.如何廉价而有效地完成这项工作?一台机器不能有超过60000个端口,所以如果我必须支持600k连接,那么我需要10个linux机箱?
由于每个连接所需的计算非常小(95%的空闲时间),一个linux盒已经可以处理600k我不想浪费金钱和资源运行10个盒子只是为了解决端口限制.
有任何想法吗?
在Unix网络编程中,有一个预分叉服务器的例子,该服务器使用Unix域管道上的消息传递来指示子进程处理传入连接:
for ( ; ; ) {
rset = masterset;
if (navail <= 0)
FD_CLR(listenfd, &rset); /* turn off if no available children */
nsel = Select(maxfd + 1, &rset, NULL, NULL, NULL);
/* 4check for new connections */
if (FD_ISSET(listenfd, &rset)) {
clilen = addrlen;
connfd = Accept(listenfd, cliaddr, &clilen);
for (i = 0; i < nchildren; i++)
if (cptr[i].child_status == 0)
break; /* available */
if (i == nchildren)
err_quit("no available children");
cptr[i].child_status = 1; /* mark child …Run Code Online (Sandbox Code Playgroud) 我想向本地网络中的所有对等方发送广播消息.消息是32位整数.我可以肯定,这个消息不会让我支离破碎,对吧?将有两个选项: - 对等体将立即接收整个消息 - 对等体根本不会接收消息
更进一步,4个字节是最大数据大小,可以在一个UDP数据报中发送?我使用基于以太网的网络占99%.
我在Unix中创建端口时遇到了麻烦.这段代码不断返回"创建socket(3)的错误",这没有任何意义,因为sockfd必须小于0才能打印错误行.
server.c:
int main (int argc, char **argv)
{
int sockfd;
struct sockaddr_in server_sockaddr;
char buff[TRANSFER_BUFFER_LEN];
/* check number of command line arguments */
if (argc < 2)
{
fprintf (stderr, "Usage: %s <port>\n");
exit (EXIT_FAILURE);
}
/* create server socket */
if ((sockfd = createUdpSocket (&sockfd,
&server_sockaddr,
atoi (*(argv + 1)))
) < 0);
{
fprintf (stderr, "Error creating socket (%d).\n", sockfd);
exit (EXIT_FAILURE);
}
...
return 0;
}
Run Code Online (Sandbox Code Playgroud)
socket_utils.h:
int createUdpSocket (int *sockfd, struct sockaddr_in *client_sockaddr, int port) …Run Code Online (Sandbox Code Playgroud) 我正在尝试制作多人网络游戏.每个玩家在屏幕上用矩形表示.我正在使用OpenGL作为图形,并且用户输入(MOVE-LEFT,MOVE-RIGHT等命令)将由它(或GLUT或sumthing)处理.
我有以下游戏架构.
游戏中有4个玩家(节点).每个播放器都使用UDP发送和接收数据.每个玩家都可以将数据发送给任何其他玩家.
如果来自相应用户的任何输入,则需要由玩家发送数据.(例如MOVE-LEFT命令等).每当玩家(比如说p1)接收到来自任何其他玩家的任何数据(比如p2)(比如屏幕上玩家p2的新位置),玩家p1的屏幕应立即更新.
我正在考虑以下几行:创建一个线程来处理图形.使用UDP创建另外2个线程,每个线程用于接收和发送数据.
每当图形线程从用户获得"myposition"的输入时,它就会更新共享的全局变量'myposition'.正在等待此变量的网络发送线程被激活,并告诉其他所有玩家新的位置.
类似地,每当从任何其他玩家"i"接收到"位置"更新时,网络接收线程更新全局变量播放器[i] .position.图形线程现在将使用更新的位置重绘场景.
这个设计是否正确.如果是,这个设计有多好,我怎样才能改进它
每当客户端连接时,我每次都会生成我的服务器.但是如果客户端在服务器上运行了相当长的时间,即多次,我经常得到*"进程中的错误<0.111.0>,退出值为:{function_clause,[{inet,tcp_close,[[]]},{run_server ,function,8}]}".*我认为它来自inet选项....请任何人都可以提出一些想法来克服错误.
出于安全考虑,我感觉应该在服务器端进行测试.尽管如此,这对服务器来说是相当沉重的,对吧?鉴于玩家正在佩戴的装备和buff,他们将具有更高的移动速度,因此每次移动时我都需要计算新的常数并查看他们的移动是否合法(使用TCP所以不必担心丢失,无序数据包).我意识到我可以只保存最后的移动速度,只有当他们改变了影响他们速度的东西时才重新计算它,但即便如此,那也是另一个检查.
我的另一个想法是服务器随机选择客户端发送它的数据并验证它并给每个客户端一个信任评级.足够低的信任评级意味着将检查来自客户端的每条消息,并且将以更详细的方式记录它们的所有操作.然后我会通过检查日志知道他们是黑客,并且可以禁止/暂停它们以及撤消它们可能通过黑客传播的任何好处.
任何建议表示赞赏,谢谢.
编辑:我刚刚意识到,黑客可以在非常高的连续性中发送微小的动作(在常规速度范围内).每个单独的运动本身就是精英,但累积的影响将是速度黑客.有什么方法可以解决这个问题?
我正在阅读Beej的" 网络编程指南 ".
在他的一个介绍示例中,他谈到了获取主机名的IP地址(例如google.com或yahoo.com).这是代码.
/*
** showip.c -- show IP addresses for a host given on the command line
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
struct addrinfo hints, *res, *p;
int status;
char ipstr[INET6_ADDRSTRLEN];
if (argc != 2) {
fprintf(stderr,"usage: showip hostname\n");
return 1;
}
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
hints.ai_socktype = SOCK_STREAM;
if ((status = getaddrinfo(argv[1], NULL, …Run Code Online (Sandbox Code Playgroud) 我正在玩套接字,我对使用带有select的阻塞套接字有一些疑问.我假设我只跟踪潜在的读者.我是否正确认为select将通过列表中的第一个套接字,如果有一些数据可用,它将返回,如果不是,它将阻塞直到select的超时到期?何时将通过select检查读取列表中的其他套接字?
让我用简单的python示例来说明:
servsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
servsock.bind(("", 2500))
servsock.listen(15)
servsock.setblocking(1)
readlist = [servsock]
while 1:
(sread, swrite, sexc) = select.select(readlist, [], [] );
for sock in sread:
#received a connect to the server socket
if sock == servsock:
(newsock, address) = servsock.accept()
newsock.setblocking(1)
print "I got a connection from ", address
readlist.append(newsock)
newsock.send("you're connected to the select server")
else:
recv_msg = sock.recv(5)
if recv_msg == "":
(host, port) = sock.getpeername()
print "Client %s:%s closed the connection" % (host,port)
sock.close()
readlist.remove(sock) …Run Code Online (Sandbox Code Playgroud) 我无法想出确切的套接字api,但我记得有一个套接字选项可以演示端口独占/非独占.
如果它不是独占的,TCP如何知道它应该转发到特定目标端口的应用程序?