c语言 一个服务端连接多个客户端,一个socket服务器端,当客户端数目多时总是连接不上!...

问题描述在这里,请大侠赐教:

http://community.csdn.net/Expert/topic/3402/3402645.xml?temp=.7895014

|

什么操作系统, 有些操作系统有最大数连接数目限制

|

那应该是程序本身的问题了.

|

server的问题。你可以加些打印,看server在什么地方出错关闭socket的。

|

看你在监听的时候设置了最大的监听等待队列数,不过在Linux中的默认值为2401,是否超过了这个数?

还有你监听的数目越多,所需要的系统资源也会越多,你的系统资源能够监听很多连接吗?

|

开大listen的backlog数,它是accept和下一次accept之间挂起的用户请求数目。如果超过这个数目的连接请求就会被拒绝,就是这样的错误信息。

|

同意楼上,可能是server程序accept处理不过来,很多在等待状态。

|

listen(x,x2)x2开大点试试

|

同时打开的文件句柄数有限制的。ulimit -a可以看到。

|

如果你的客户端连接不上是connect出错,看一下errno.如果是因为没有回包,要看你的server处理到哪一步。程序写得不好。Nonblock socket的很多读写没有错误处理,错误消息很少。结构不好,象个大杂烩。

|

nofiles(descriptors) 1024!

|

嗯,最多1024个打开文件。另外,如果用的是线程处理的话,还受到堆栈内存的限制。

|

还是从accept报错的地方把错误的errno,以及perror出来看看吧。

|

tcpdump 查查网络包的状态

|

一个进程同时打开的文件句柄时有限制的,你可以看看这个超过了没

|

从你上面列出的系统限制信息来看,在打开的文件描述字和堆栈方面都有限制,其实,每个socket也是一个文件描述字的.

客户端打印消息:: Connection reset by peer

从这里来看是服务器端出问题了.

|

不好意思,没写完不小心按提交了。

续上

在linux下,对于每个socket,内核维护2个队列:

1:未完成的连接队列

客户端发送的SYN分节已到达服务器端,服务器正在等待完成相应的TCP三路握手过程。内核将这样的客户放置在未完成连接的队列中,这些socket处于SYN_RCVD状态。

2:已完成的连接队列

每个已完成三路握手的客户存放在此队列中,这些socket处于ESTALISHED状态。

accept每次从已完成的连接队列中取出一个客户。如果此队列为空,那么服务器端的进程就进入睡眠状态(假设socket为缺省的阻塞方式)

当一个客户的SYN到达时,若这两个队列都是满的,TCP就会忽略这个SYN,客户端就会连接不上。

在比较繁忙的服务器端,应该采用多线程,主线程监听,每来一个客户端,开一个线程去处理该客户端。

listen()

while(true)

{

accept()

pthread_create()

}

而且,while循环中的代码尽量减少,执行越快越好。

|

TCP/IP工作原理

在linux下,对于每个socket,内核维护2个队列:

1:未完成连接的队列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的示例程序,展示了如何使用C语言编写一个基本的socket通信程序,实现多个客户端连接一个服务器。 Server端代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #define PORT 8080 int main(int argc, char const *argv[]) { int server_fd, new_socket, valread; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); char buffer[1024] = { 0 }; char *hello = "Hello from server"; // 创建socket if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // 设置socket选项 if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { perror("setsockopt"); exit(EXIT_FAILURE); } // 设置socket地址结构 address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); // 绑定socket if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } // 监听socket if (listen(server_fd, 3) < 0) { perror("listen"); exit(EXIT_FAILURE); } // 接受客户端连接 while (1) { if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) { perror("accept"); exit(EXIT_FAILURE); } // 读取客户端发送的消息 valread = read(new_socket, buffer, 1024); printf("%s\n", buffer); // 向客户端发送消息 send(new_socket, hello, strlen(hello), 0); printf("Hello message sent\n"); // 关闭连接 close(new_socket); } return 0; } ``` Client端代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #define PORT 8080 int main(int argc, char const *argv[]) { int sock = 0, valread; struct sockaddr_in serv_addr; char *hello = "Hello from client"; char buffer[1024] = { 0 }; // 创建socket if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("\n Socket creation error \n"); return -1; } // 设置socket地址结构 serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); // 将IPv4地址从点数转换为二进制数 if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { printf("\nInvalid address/ Address not supported \n"); return -1; } // 连接服务器 if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { printf("\nConnection Failed \n"); return -1; } // 向服务器发送消息 send(sock, hello, strlen(hello), 0); printf("Hello message sent\n"); // 读取服务器返回的消息 valread = read(sock, buffer, 1024); printf("%s\n", buffer); // 关闭socket连接 close(sock); return 0; } ``` 使用方法: 1. 在终端中分别编译Server和Client代码: ```bash $ gcc server.c -o server $ gcc client.c -o client ``` 2. 在一个终端窗口中启动Server: ```bash $ ./server ``` 3. 在另一个终端窗口中启动Client: ```bash $ ./client ``` 4. 查看Server端终端窗口,应该可以看到输出了客户端发送的消息,并且向客户端发送了回复。 注意事项: - 程序中使用了本地IP地址(127.0.0.1)作为服务器地址,如果需要在局域网内使用,需要将其修改为服务器的实际IP地址。 - 程序中使用了固定的端口号(8080),如果需要使用其他端口号,需要将其修改为实际需要使用的端口号。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值