linux套接字编程

本文详细介绍了一种基于TCP协议的套接字编程方法,包括服务器端和客户端的初始化过程,以及读写操作的封装。通过具体的代码示例,帮助读者理解如何建立连接并进行数据交换。

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


头文件:

#include <sys/types.h>		//定义数据类型
#include <sys/socket.h>		//提供套接字接口和数据结构
#include <netinet/in.h>		//定义数据结构sockaddr_in
#include <arpa/inet.h>		//提供ip地址转换函数</span>

服务器:

//套接字初始化, client_sock:输出参数,用于通信的客户端套接字,  prot:端口号,  ip_address:ip地址,默认为NULL表示接收任意网络的连接
//成功则返回true, 失败则返回false
bool server_sock_init(int * client_sock, int port, const char *ip_address)
{
	int server_sock_fd;
	struct sockaddr_in server_sock_address;
	int en = 1;
	//创建未命名套接字
	if((server_sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
		cout<<"failed to create server socket."<<endl;
		return false;
	}

	if (setsockopt(server_sock_fd, SOL_SOCKET, SO_REUSEADDR, &en, sizeof (int)) == -1)
		cout<<"failed to set reused address."<<endl;

	server_sock_address.sin_family = AF_INET;
	if(ip_address == NULL)
		server_sock_address.sin_addr.s_addr = INADDR_ANY;		//允许来自任何网络接口的链接
	else
		server_sock_address.sin_addr.s_addr = inet_addr(ip_address);
	server_sock_address.sin_port = htons (port);		//将主机字节序转化为网络字节序,保证端口号正确
	memset (&(server_sock_address.sin_zero), '\0', 8);	//填充无意义的字节

	//命名套接字
	if (bind(server_sock_fd, (struct sockaddr *) &server_sock_address, sizeof (struct sockaddr)) == -1){
		cout<<"failed to bind server socket."<<endl;
		return false;
	}

	//创建监听队列
	if (listen (server_sock_fd, 5) == -1){
		cout<<"failed to listen server socket."<<endl;
		return false;
	}

	//等待一个客户端连接
	struct sockaddr_in client_address;
	socklen_t client_length = sizeof(struct sockaddr_in);
	cout<<"waiting connect..."<<endl;
	if((*client_sock = accept(server_sock_fd, (struct sockaddr *)&client_address, &client_length)) == -1){
		cout<<"failed to accept a connect."<<endl;
		return false;
	}
	cout<<"connected from "<<inet_ntoa(client_address.sin_addr)<<endl;
	return true;
}

客户端:

//server_sock->输出参数,用于网络通信的文件描述符
//port->端口号
//ip_address->ip地址
bool client_sock_init(int *server_sock, int prot, const char * ip_address)
{
	int len;
	struct sockaddr_in server_address;
	if((*server_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1){
		cout<<"failed to create server socket."<<endl;
		return false;
	}

	server_address.sin_family = AF_INET;
	server_address.sin_addr.s_addr = inet_addr(ip_address);
	server_address.sin_port = htons(prot);
	len = sizeof(server_address);

	if(connect(*server_sock, (struct sockaddr *)&server_address, len) == -1){
		cout<<"failed to connect server"<<endl;
		return false;
	}
	return true;
}

读写套接字封装:

//发送数据, 成功则返回未发送完的字节数, 失败则返回-1
int write_sock(int sock_fd, char *buf, int length)
{
	int byte_send;
	if((byte_send = write(sock_fd, buf, length)) == -1){
		cout<<"error in write sock."<<endl;
		return -1;
	}
	else
		return length - byte_send;
}

//接收数据, 返回未接收到的字节数
int read_sock (int sock_fd, char *buf, int length)
{
	int byte_read = -1;
	char *ptbuf =buf;
	int mlength = length;
	int count = 0;
	do
	{
		byte_read = read (sock_fd, ptbuf,mlength);
		if (byte_read > 0)
		{
			ptbuf = ptbuf+byte_read;
			mlength = mlength-byte_read;
		}
		else
			return -1;
		count++;
		if(count > 10000)
			return -1;
	}while(mlength > 0);
	return mlength;
}


写好这些函数后,在服务器端,只需要定义一个一个客户端套接字int client_sock; 再用它作为输出参数调用server_sock_init()函数就可以初始化套接字,在server_sock_init()函数中会等待客户端连接。 在客户端程序中,只需要定义一个服务器套接字int server_sock; 在用它作为输出参数调用client_sock_init()函数就可以初始化套接字并连接服务器。如果连接成功,双方就可以使用write_sock()和read_sock()进行通信了。






一、计任务 完成在如下两个题目中任选一个题目。 1、网络数据计算 (1)在Linux系统下,使用TCP协议套接字编程; (2)服务器应具有处理多个客户端连接并计算的能力; (3)过程描述 客户端:连接服务器后,从键盘输入一连串的整数及字符串,并将这些整数及字符串发送到服务器,并发送结束指令(自定义结束指令),等待服务器返回计算结果,显示结果后退出; 服务器:为每个客户连接创建一个进程,处理客户数据,显示每次收到一个整数或字符串,收到结束指令后将整数累加,并将累加结果返回客户端,并关闭连接,结束进程。 2、linux系统下实现聊天室 (1)在Linux系统下,使用TCP协议套接字编程; (2)服务器应具有处理多个客户端连接能力(定最大连接数,如5个); (3)具有群发和私聊的能力; (4)过程描述 客户端:连接服务器后,应能接收服务器发来信息并处理的能力,当收到聊天信息时,显示群发或私聊、信息发送客户及发送的信息,当收到客户加入或退出时,显示客户登录或退出,并更新客户列表;每次可选择群发或私聊,群发时将键盘输入信息发送给服务器,私聊时,选择私聊客户并将输入信息发送给服务器。选择退出时,结束进程或线程,关闭程序。 服务器:为每个客户连接创建一个进程或线程,处理客户信息,当有新客户加入或有客户退出时,将客户加入或退出信息发送给每个客户端;当收到某客户的群发信息时,将信息转发给每个客户,当收到客户私聊时将信息转发给私聊客户;客户退出时关闭相应的进程或线程。 二、计时间 一周 三、计说明书 每名学生完成计任务的同时,撰写计说明书,见附件,可打印也可手写,但不得抄袭。 四、计成绩评定标准 计根据学生在计过程的出勤、学习态度及计任务完成情况综合评定计成绩,具体分值所占比例为: (1)出勤、上机态度占总成绩20%,若发现做与计无关事情,每次扣5分; (2)计说明书占总成绩40%,若发现有抄袭行为,计成绩为不及格; (3)计完成效果及答辩占总成绩40%。 按照优、良、中、及格和不及格五级给予最终成绩。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值