MultiSocket 监听 Linux 套接字编程
Posted
技术标签:
【中文标题】MultiSocket 监听 Linux 套接字编程【英文标题】:MultiSocket Listening Linux Socket Programing 【发布时间】:2014-02-10 22:58:49 【问题描述】:这是我编写的简单代码。服务器响应端口 2923、2924 和 2925 上的 CONNECTIONS。
当我运行程序时,服务器只接受来自 2923 端口的连接。有人可以帮帮我吗?谢谢
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
void handle_client(int cliend_fd)
int ret = accept(cliend_fd, NULL, 0);
if (ret < 0)
printf("Accept Error\n");
else
printf("Client Accepted\n");
shutdown(ret, 2);
int main()
int count = 3;
int PORT = 2923;
struct sockaddr_in address;
int MasterSocket[count];
int i = 0;
fd_set readfds;
int maxfd;
maxfd = -1;
int SelectSession;
struct timespec TimeOut;
TimeOut.tv_sec = 2;
TimeOut.tv_nsec = 2;
for (i = 0; i < count; i++)
MasterSocket[i] = socket(AF_INET, SOCK_STREAM, 0);
for (i = 0; i < count; i++)
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_port = PORT + i;
if (bind(MasterSocket[i], (struct sockaddr *) &address, sizeof(address))
< 0)
perror("Bind\n");
getchar();
printf("SockerDesriptor %d---bind %d\n", MasterSocket[i], PORT + i);
for (i = 0; i < count; i++)
if (listen(MasterSocket[i], 4) < 0)
perror("Listen");
getchar();
//return 1;
else
printf("Listening on Port %d---\n", PORT + i);
while (1)
FD_ZERO(&readfds);
int status;
for (i = 0; i < count; i++)
FD_SET(MasterSocket[i], &readfds);
if (MasterSocket[i] > maxfd)
maxfd = MasterSocket[i];
printf("%d Added to FD_SET Descriptor %d \n\n", PORT + i,
MasterSocket[i]);
//status = 0;
printf("############Waiting for Connection\n");
status = pselect(maxfd + 1, &readfds, NULL, NULL, &TimeOut, NULL );
if (status < 0)
perror("Status");
getchar();
return 1;
else if (status == 0)
printf("TimeOut occured\n");
else
//printf("Status %d\n", status);
SelectSession = -1;
for (i = 0; i < count; i++)
//printf("Checking Set %d\n", i);
if (FD_ISSET(MasterSocket[i], &readfds))
//printf("Matching Set %d\n", i);
SelectSession = MasterSocket[i];
printf("SelectSession %d\n", MasterSocket[i]);
if (SelectSession == -1)
//shutdown (MasterSocket[i], 2);
//continue;
break;
else
printf("In Handle\n");
handle_client(SelectSession);
getchar();
else
printf("Not in FD_ISSET\n");
/*for (i=0; i<count; i++)
shutdown (MasterSocket[i], 2);
*/
return 0;
【问题讨论】:
在程序执行过程中,bind()
、listen()
、pselect()
和/或accept()
是否有任何错误?
代码编译时没有警告吗?
这里的代码在完成#define _POSIX_C_SOURCE 200112L
后编译干净,以提取pselect()
的原型并按预期工作。
你用什么连接服务器?
使用了客户端程序。连接端口。仅接受 2923
【参考方案1】:
从 while 循环中删除 getchar()
。
在pselect
服务器等待获取字符之后,因此不再允许连接客户端。
或者你必须在每个客户端连接后在服务器中输入一个字符
并使用htons
将端口号更改为网络字节顺序
程序:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
void handle_client (int cliend_fd)
int ret = accept(cliend_fd, NULL, 0);
if ( ret < 0 )
printf("Accept Error\n");
else
printf ("Client Accepted\n");
shutdown (ret, 2);
return;
int main()
int count = 3, PORT = 8000, opt = 1, i = 0;
int MasterSocket[count];
int maxfd = -1, SelectSession;
fd_set readfds;
struct sockaddr_in address;
struct timespec TimeOut;
TimeOut.tv_sec = 2;
TimeOut.tv_nsec = 2;
for(i=0; i<count; i++)
MasterSocket[i] = socket(AF_INET , SOCK_STREAM , 0);
printf("socket created : %d\n", MasterSocket[i]);
for(i=0; i<count; i++)
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr("192.168.1.4");
address.sin_port = htons(PORT+i);
if( setsockopt(MasterSocket[i], SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 )
perror("setsockopt1");
return -1;
if (bind(MasterSocket[i], (struct sockaddr *)&address, sizeof(address)) < 0)
perror ("Bind\n");
return -1;
printf("SockerDesriptor %d---bind %d\n", MasterSocket[i], PORT+i);
for(i=0; i<count;i++)
if (listen(MasterSocket[i], 4) < 0)
perror ("Listen\n");
return -1;
else
printf("Listening on Port %d---\n", PORT+i);
while(1)
FD_ZERO(&readfds);
int status;
for (i = 0; i < count; i++)
FD_SET(MasterSocket[i], &readfds);
if (MasterSocket[i] > maxfd)
maxfd = MasterSocket[i];
status = pselect(maxfd + 1, &readfds, NULL, NULL, &TimeOut, NULL );
if(status < 0)
perror("Status");
/* else if(status == 0)
printf("TimeOut occured\n"); */
else if(status > 0)
for (i = 0; i < count; i++)
if (FD_ISSET(MasterSocket[i], &readfds))
SelectSession = MasterSocket[i];
printf("SelectSession %d\n", MasterSocket[i]);
handle_client(SelectSession);
//getchar();
return 0;
【讨论】:
工作中...感谢您的帮助 \m/。是的,我查了SO_REUSEADDR
和getchar()
。我忽略了一个小细节。我用count +1
调用了“pselect”而不是maxfd+1
【参考方案2】:
这一行
address.sin_port = PORT + i;
应该是
address.sin_port = htons(PORT + i);
确保端口按网络字节顺序存储。
另外你应该close()
一个套接字描述符在关闭它之后,如果你不再需要它,释放与之相关的系统资源。
【讨论】:
以上是关于MultiSocket 监听 Linux 套接字编程的主要内容,如果未能解决你的问题,请参考以下文章