【学习笔记】网络编程:基于TCP/IP的socket链路建立

一、关键字

不同PC的进程间通信、OSI系统模型、TCP/IP系统模型、TCP/IP协议、TCP数据包格式、网络解包和封包过程、网络字节序、套接字

二、基于TCP/IP的socket通信

1.服务器端流程及接口展示

创建socket监听套接字文件描述符

/**********************************************************
*函数功能:创建一个套接字文件描述符                          
*参数: domain:协议族(AF_INET,AF_INET6)
*      type:协议类型
*      protocol:一般取0
* 返回值:成功:返回套接字文件描述符
*        失败:返回-1(错误码放在errno中)       
**********************************************************/
int socket(int domain, int type, int protocol);

绑定自己的IP(和端口号)

/*********************************************************
*函数功能:绑定一个套接字
*参数:sockfd:套接字文件描述符
*      addr:结构体指针,存放IP、端口、协议族等信息
*      addlen:结构体大小
* 返回值:成功返回0
*        失败:返回-1(错误码放在errno中)
*********************************************************/
int bind(int sockfd, struct sockaddr* addr, int addlen)

监听客户端连接

/**********************************************************
*函数功能:监听、等待客户端连接
*参数:socket:套接字文件描述符
*     backlog:可排队连接的最大连接数
* 返回值:成功:返回0
*        失败:返回-1(错误码放在errno中)
**********************************************************/
int listen(int socket, int backlog)

接受客户端的连接请求

/**********************************************************
*函数功能:TCP服务器接收客户端连接请求
*参数:sockfd:套接字问价描述符
*      addr:接收客户端IP信息
*      addlen:addr结构体大小
* 返回值:成功:返回交互套接字文件描述符
*        失败:返回-1(错误码放在errno中)
**********************************************************/
int accept(int sockfd, struct sockaddr* addr,int *addlen)

接收(发送)数据

/*************************************************************
*函数功能:向一个已经连接的套接字发送数据
*参数:sockfd:已连接套接字文件描述符
*      buf:数据缓冲区指针,用于存放要发送的数据
*      len:要发送的数据长度
*      flags:调用执行方式,一般设为0
* 返回值:成功:返回发送的数据总数
*        失败:-1(错误码放入errno)
*************************************************************/
size_t send(int sockfd, const void* buf, size_t len, int flags)
/*************************************************************
*函数功能:向一个已经连接的套接字发送数据
*参数:sockfd:已连接套接字文件描述符
*      buf:数据缓冲区指针,用于存放接收的数据
*      len:数据缓冲区的长度
*      flags:调用执行方式,一般设为0
* 返回值:成功:返回发送的数据总数
*        失败:-1(错误码放入errno)
*************************************************************/
size_t recv(int sockfd, void* buf, size_t len, int flags)

关闭套接字

int close(int socket)

2.客户端流程及接口展示

创建socket套接字文件描述符
连接服务器

/***********************************************************
*函数功能:建立与TCP服务器的连接
*参数:sockfd:套接字文件描述符
*      addr:服务器端的IP和端口信息
*      addlen:addr结构体长度
*返回值:成功:返回0
*        失败:返回-1(错误码放入errno)
***********************************************************/
int connect(int sockfd, struct sockaddr* addr, int addlen)

发送接收消息
关闭套接字

三、代码

1.服务器端

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>


int SERVER_SOCKET_INIT()
{
	int sock = 0;
	struct sockaddr_in server_ip;
	sock = socket(AF_INET, SOCK_STREAM, 0);
	if (sock < 0) {
    	perror("socket");
    	return -1;
    } 

	memset(&server_ip, 0, sizeof(server_ip));
	server_ip.sin_family = AF_INET;
	server_ip.sin_port = htons(52013);
	server_ip.sin_addr.s_addr = inet_addr("127.0.0.1");
    if (bind(sock, (struct sockaddr*)&server_ip, sizeof(server_ip)) < 0) {
    	perror("bind");
    	close(sock);
    	return -1;
	}
	
	if (listen(sock,1024) < 0) {
		perror("listen");
		close(sock);
		return -1;
	}

	printf("服务器准备就绪...\n");
	printf("等待客户端连接...\n");
	return sock;
}

int SERVER_METH()
{
	char buffer[1024];
	int sock, server_sock, len;
	struct sockaddr_in client_ip;
	
	sock = SERVER_SOCKET_INIT();
	if (sock < 0) {
		printf("服务器初始化失败!\n");
		return -1;
	}
	
	memset(&client_ip, 0, sizeof(client_ip));
	len = sizeof(client_ip);
	
	while(1) {
		server_sock = accept(sock, (struct sockaddr*)&client_ip, &len);
		if (server_sock < 0) {
			continue;
		} else {
			printf("[%s:%d]用户已连接!\n", inet_ntoa(client_ip.sin_addr), ntohs(client_ip.sin_port));
			memset(buffer, 0, sizeof(buffer));
			strcpy(buffer,"欢迎使用流星系统,服务器连接成功!\n");
			if (send(server_sock, (char*)buffer, strlen(buffer), 0) <= 0) {
				perror("send");
				close(sock);
				close(server_sock);
				return -1;
			}
			memset(buffer, 0, sizeof(buffer));
			if (recv(server_sock, (char*)buffer, sizeof(buffer) - 1, 0) <= 0) {
				perror("recv");
				close(sock);
				close(server_sock);
				return -1;
			}
			printf("[%s:%d]:%s\n", inet_ntoa(client_ip.sin_addr), ntohs(client_ip.sin_port), buffer);
			printf("[%s:%d]:已断开!\n", inet_ntoa(client_ip.sin_addr), ntohs(client_ip.sin_port));
			memset(buffer, 0, sizeof(buffer));
			close(server_sock);
		}
	}
	close(sock);
	return 0;
}

int main()
{
	int ret = SERVER_METH();
	if (ret < 0) {
		printf("服务器建联失败!\n");
		return -1;
	}
}

2.客户端代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main()
{
	char buffer[1024];
	int sock;
	struct sockaddr_in server_ip;
	
	sock = 	socket(AF_INET, SOCK_STREAM, 0);
	if (sock < 0) {
		perror("socket");
		close(sock);
		return -1;
	}
	
	memset(&server_ip, 0, sizeof(server_ip));
	server_ip.sin_family = AF_INET;
	server_ip.sin_port = htons(52013);
	server_ip.sin_addr.s_addr = inet_addr("127.0.0.1");
	if(connect(sock, (struct sockaddr*)&server_ip, sizeof(server_ip)) < 0) {
		perror("connect");
		close(sock);
		return -1;
	}
	printf("[%s:%d]:服务器连接成功!\n",inet_ntoa(server_ip.sin_addr),ntohs(server_ip.sin_port));
	memset(buffer, 0, sizeof(buffer));
	if(recv(sock, (char*)buffer, sizeof(buffer) - 1, 0) < 0) {
		perror("recv");
		close(sock);
		return -1;
	}
	printf("[%s:%d]:%s\n", inet_ntoa(server_ip.sin_addr), ntohs(server_ip.sin_port), buffer);
	memset(buffer, 0, sizeof(buffer));

	strcpy(buffer, "流星系统,你好!");
	if(send(sock, (char*)buffer, strlen(buffer), 0) < 0)
	{
		perror("send");
		close(sock);
		return -1;
	}
	close(sock);
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值