最近在看libevent
网络库时,发现网络编程还可以这样写,将服务器的创建和客户端的创建写在同一个函数中,最终将他们返回的套接字放入一个fd[2]
数组中,这样就可以在多个程序中复用这两个描述符。最终写了一个简单的小例子进行说明。
listen()
listen()
函数的作用是监听服务器端创建的套接字是否有对端进行连接,并且可以指定最大的连接数目。
但与此同时listen
会将socket()
创建的主动套接字转换为被动套接字,等待客户端的连接请求。
当客户端执行connect()
后,服务器端就已经监听到了这个请求,只是没有建立连接,建立连接这一步在accept()
这一步中完成。
accept()
客户端调用connect()
后向服务器端发送了一个请求,而此时服务器使用listen()
监听到这个请求之后会调用accept()
接受请求,从而创建连接,这样就能够进行I/O操作了。
accept()
会返回一个套接字描述符,实际上进行I/O操作的应该为accept()
返回的这个描述符,因为它能够描述通信双方的信息。
/*************************************************************************
> File Name: lis_con.c
> Author: xz
> Created Time: Wed 15 May 2019 08:31:20 PM PDT
************************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
int get(int fd[2]) {
int lisfd, confd;
struct sockaddr_in serAddr;
struct sockaddr_in cliAddr, lisAddr;
lisfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serAddr, 0, sizeof(serAddr));
serAddr.sin_family = AF_INET;
serAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
serAddr.sin_port = 0;
bind(lisfd, (struct sockaddr*)&serAddr, sizeof(serAddr));
if (listen(lisfd, 1) != -1)
printf("listen success\n");
printf("hello\n");
int lisAddrLen = sizeof(lisAddr);
if (getsockname(lisfd, (struct sockaddr*)&lisAddr, &lisAddrLen) != -1)
printf("getsockname\n");
confd = socket(AF_INET, SOCK_STREAM, 0);
memset(&cliAddr, 0, sizeof(cliAddr));
if (connect(confd, (struct sockaddr*)&lisAddr, sizeof(lisAddr)) != -1)
printf("connect success\n");
int cliAddrLen = sizeof(cliAddr);
int accfd = accept(lisfd, (struct sockaddr*)&cliAddr, &cliAddrLen);
if (accfd > 0) {
printf("accept\n");
}
fd[0] = confd;
fd[1] = accfd;
return 0;
}
int main() {
int fd[2] = {0};
int nRead, nWrite;
char buf[] = "ceshiyixiala";
char buf2[1024];
get(fd);
printf("%d, %d\n", fd[0], fd[1]);
nWrite = write(fd[0], buf, sizeof(buf));
if (nWrite == 0) {
printf("read error\n");
}
printf("write %d bytes. buf:%s\n", nWrite, buf);
nRead = read(fd[1], buf2, 1024);
printf("read %d bytes, read buf:%s\n", nRead, buf2);
}
这个例子并没有进行错误的判断,只是进行问题的说明。