套接字编程--小点

本文介绍了一种在libevent网络库中实现服务器和客户端创建的方法,通过在一个函数中同时创建并返回两个描述符,实现了在多个程序中复用的目的。详细解析了listen(), accept() 和 connect() 函数的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在看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);
}

这个例子并没有进行错误的判断,只是进行问题的说明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值