Socket 编程介绍与应用(一) : 简单的TCP套接字实现

1.什么是Socket?

Socket = 套接字 , 它是计算机之间进行通信的一种约定或一种方式。
通过 socket 这种约定 , 一台计算机可以接收其他计算机的数据 , 也可以向其他计算机发送数据。

2.为什么要使用Socket?

计算机之间进行网络通讯的工作为 7 层(OSI模型) :
从下到上分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。

而后来因为复杂性而简化为 4 层(TCP/IP 模型) :
从下到上分别是接口层、网络层、传输层和应用层。

我们所说的 socket 编程 , 是站在传输层的基础上 , 所以可以使用 TCP/UDP 协议经由网络模型的封装后实现在网络中发送数据。

3.怎么使用Socket?

3.1 server基础语法(windows)

#include <stdio.h>
#include <winsock2.h>
#pragma comment (lib, "ws2_32")

int main(){
	// 初始化winsock2 Dll , 此处第一个参数对应socket的版本号2.2 , 第二次参数对应的是Socket细节
	WSADATA  wsData;
	WSAStartup(MAKEWORD(2, 2), &wsData);

	// 创捷套接字 , 第一个参数对应的是IP协议 , 第二个则是套接字类型 , 第三个为特定协议(填0系统会自动判断)
	SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	
	// 设置地址 , 绑定套接字 , 用于接下来的数据监听
	sockaddr_in sAddr;
    memset(&sAddr, 0, sizeof(sAddr));  //每个字节都用0填充
	serAddr.sin_family = AF_INET;/* 对应上面分AF_INET , 代表的是使用ipv4 */
	serAddr.sin_port = htons(/* server开放的端口号 */);
	serAddr.sin_addr.S_un.S_addr = inet_addr(/* server的IP地址 */);
	bind(sock, (struct sockaddr*) & sAddr, sizeof(sAddr));

	// 监听socket , 	第一个参数对应需要被监听的sock , 此处的sock对应的是server的地址信息 , 
	//				第二个参数是数据队列最多可以容纳多少个客户端排队连接
	listen(sock , 20);
	
	// 响应连接请求 , 函数accept()如果没有连接将会阻塞
	struct sockaddr cAddr;
	int cSize = sizeof(struct sockaddr);
	SOCKET clientSock = accept(sock, (struct sockaddr*) & cAddr, &cSize);

	// 发送数据给客户端 , 其实send是将数据放入TCP的发送缓冲中 , 具体发送时间由TCP协议自己控制
	char * str = "Hello Socket";
	send(clientSock, str, strlen(str)+1, NULL);

	// 发送后关闭套接字
	closesocket(clientSock);
	closesocket(sock);
	
	// 停止Dll
	WSACleanup();
	return 0;
}

3.1 client基础语法(windows)

#include <stdio.h>
#include <winsock2.h>
#pragma comment (lib, "ws2_32")

int main(){
	// 初始化winsock2 Dll , 此处第一个参数对应socket的版本号2.2 , 第二次参数对应的是Socket细节
	WSADATA  wsData;
	WSAStartup(MAKEWORD(2, 2), &wsData);

	// 创捷套接字 , 第一个参数对应的是IP协议 , 第二个则是套接字类型 , 第三个为特定协议(填0系统会自动判断)
	SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	
	// 设置地址 , 绑定套接字 , 准备进行连接
	sockaddr_in sAddr;
    memset(&sAddr, 0, sizeof(sAddr));  //每个字节都用0填充
	serAddr.sin_family = AF_INET;/* 对应上面分AF_INET , 代表的是使用ipv4 */
	serAddr.sin_port = htons(/* server开放的端口号 */);
	serAddr.sin_addr.S_un.S_addr = inet_addr(/* server的IP地址 */);

	// 进行连接 , 此时服务器的accept端口将取消阻塞向下执行
	connect(sock, (struct sockaddr*) & sAddr, sizeof(sAddr));


	
	// 接收服务器传回的数据 , 函数accept()如果没有连接将会阻塞
	char strBuf[100] = { 0 };
	recv(sock, strBuf, 100, NULL);
	printf(" 服务器传入的数据是 : %s \n",strBuf);
	// ** 此处数据结果是 "服务器传入的数据是 : Hello Socket" **

	// 接收后后关闭套接字
	closesocket(sock);
	
	// 停止Dll
	WSACleanup();    
	
	system("pause");
	return 0;
}

总结

上面描述了最基础的windows下socket的编程方法 , 如果不好理解你可以看看我在下面描述的比喻.

TCP的连接方式是持续的 , 你可以将其理解为高铁的运输 , 而你是这班高铁的站长 , 你要传输的数据就是你的乘客

其一物理链接是高铁的轨道 , 没有轨道一切都免谈 ; 并且轨道的质量将决定你车的速度 , 就算你是最好的车 , 开到一半轨道断了也没办法继续跑了 , 只能换个轨道重新跑 ;

第二TCP协议就是你的车 , 没有TCP协议就算有轨道乘客也没办法从你这里到达目标地点. 如果你用错了协议 , 比如上面的程序 , 你使用了UDP , 如果你的目标地点不支持UDP这辆车你的乘客也没法到达目的地.

那么现在你有了铁轨 , 有了车 , 想要让数据上车或者下车 , 那么就需要岳台 , 岳台就是TCP的缓冲区 , 这个缓冲区呢有自己的安保人员 , 负责你乘客的上下车 , 而你只需要告诉乘客去哪个岳台即可.

最后你的乘客上了车 , 到达了目标地点 , 目标地点也同样识别TCP这辆车 , 那乘客就可以成功的下车了.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值