我是Unix / Linux网络编程的新手,所以我在下面编写了服务器 - 客户端程序。在这段代码中,客户端和服务器之间有一个套接字,客户端请求服务器,然后服务器响应从1到100的数字到客户。所以我的问题是如何在不使用线程的情况下使用3套接字(tcp连接)来完成此过程? (例如,第一个套接字运行然后第二个运行,然后第三个运行,然后再次运行。)你有任何建议吗?
Client.c
int main()
{
int sock;
struct sockaddr_in sa;
int ret;
char buf[1024];
int x;
sock = socket (AF_INET, SOCK_STREAM, 0);
bzero (&sa, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(SERVER_PORT);
inet_pton (AF_INET, SERVER_IP, &sa.sin_addr);
ret = connect (sock,
(const struct sockaddr *) &sa,sizeof (sa));
if (ret != 0) {
printf ("connect failed\n");
exit (0);
}
x = 0;
while (x != -1) {
read (sock, buf , sizeof(int));
x = ntohl(*((int *)buf));
if (x != -1)
printf ("int rcvd = %d\n", x);
}
close (sock);
exit (0);
}
Server.c
int main()
{
int list_sock;
int conn_sock;
struct sockaddr_in sa, ca;
socklen_t ca_len;
char buf[1024];
int i;
char ipaddrstr[IPSTRLEN];
list_sock = socket (AF_INET, SOCK_STREAM, 0);
bzero (&sa, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = htonl(INADDR_ANY);
sa.sin_port = htons(SERVER_PORT);
bind (list_sock,(struct sockaddr *) &sa,sizeof(sa));
listen (list_sock, 5);
while (1){
bzero (&ca, sizeof(ca));
ca_len = sizeof(ca); // important to initialize
conn_sock = accept (list_sock,(struct sockaddr *) &ca,&ca_len);
printf ("connection from: ip=%s port=%d \n",inet_ntop(AF_INET, &(ca.sin_addr),
ipaddrstr, IPSTRLEN),ntohs(ca.sin_port));
for (i=0; i<100; ++i){
*((int *)buf) = htonl(i+20);
// we using converting to network byte order
write (conn_sock, buf, sizeof(int));
}
* ((int *)buf) = htonl(-1);
write (conn_sock, buf, sizeof(int));
close (conn_sock);
printf ("server closed connection to client\n");
}
}
答案 0 :(得分:0)
我认为最好查看优秀的资源Beej's Guide to Netwokr Programming,详细了解这一点。他还有一些很好的例子,你可以用它作为起点,他涵盖了包括windows在内的所有主要平台。
基本上你这样做:
socket()
bind()
listen()
accept()
accept()返回连接到唯一客户端的套接字。然后,您将使用select,poll或epoll来确定这些套接字上的数据何时可用。我建议您查看这些API和Beej指南的手册页。这是我第一次学习网络编程的地方。
查看代码,你的内循环是错误的。接受连接时,需要将其添加到列表或其他内容中。目前,您覆盖它并将其松散。您应该使用(e)民意调查或选择告诉您哪些数据。您可以随时写信给他们中的任何一个。再看一下Beej指南中的例子,它们是最有帮助的。
答案 1 :(得分:0)
也许这不是你想要的,但我认为你可以试试epoll,有一个简单的例子
typedef struct event_loop
{
int max_event;
int epfd;
}event_loop;
event_loop* create_event_loop()
{
event_loop *ep = malloc(sizeof(event_loop));
ep->max_event = 512;
ep->epfd = epoll_create(512);
return ep;
}
int add_event(event_loop *ep, int fd)
{
epoll_event ee;
ee.data.fd = fd;
ee.event = EPOLLIN | EPOLLPRI;
epoll_ctl(ep->epfd, EPOLL_CTL_ADD, fd, &ee);
}
void event_main(event_loop *ep, int listenfd)
{
epoll_event events[512];
int nfds, i, newfd;
while(1)
{
if(nfds = epoll_wait(ep->epfd, events, 512, -1) == -1)
exit(1);
for(i = 0; i < nfds; i++)
{
if(events[nfds].data.fd == listenfd)
{
newfd = accept(listenfd, NULL, NULL);
add_event(ep, newfd);
}
else
{
//do what you want
}
}
}
}
epoll是一种高效解决方案,只需man epoll
获取更多信息