网络编程(2):socket、c/s模型socket建立

一、C/S模型
建立完整的TCP网络服务
在这里插入图片描述
客户端不需要bind,服务端需要bind:
因为客户端寻找服务端,因此需要绑定一个IP,同一个主机上有多个端口,因此需要绑定一个端口来监听是否有客户端寻求连接

二、windows需要初始化winsock2库,才能运行

#define WIN32_LEAN_AND_MEAN
#include<windows.h>
#include<WinSock2.h>//windos.h和winsock2.h有宏定义冲突
//需要在添加对应的库ws2_32.lib
//与linux相比,windows需要启动winsock库
int main() {
	WORD ver = MAKEWORD(2, 2);//创建版本号
	WSADATA dat;
	WSAStartup(ver, &dat);//启动socket网络
	/*   */
	WSACleanup();//关闭socket网络
	return 0;
}

三、建立服务端:
1)创建socket,
socket( _In_ int af, _In_ int type, _In_ int protocol );af 是IP地址族,type套接口的类型,protocol使用的传输协议,windows返回的是一个socekt,linux返回的是int,此时socket可能是INVALID_SOCKET

2)bind一个端口bind( _In_ SOCKET s, _In_reads_bytes_(namelen) const struct sockaddr FAR * name, _In_ int namelen );第一个参数是套接字,第二个参数是一个指向特定协议的地址结构的指针,第三个参数是该地址结构的长度

3)监听listen( _In_ SOCKET s, _In_ int backlog );第一个参数为套接字,第二个为允许多少客户端访问

4)等待客户端连接accept( _In_ SOCKET s, _Out_writes_bytes_opt_(*addrlen) struct sockaddr FAR * addr, _Inout_opt_ int FAR * addrlen );第一个参数为服务端套接字,第二个为客户端协议的地址,第三个为客户端协议地址的长度,会生成新的socket之后的通信使用该套接字

5)发送数据send(
In SOCKET s,
In_reads_bytes(len) const char FAR * buf,
In int len,
In int flags
);第一个为客户端的套接字,第二个为发送的数据(必须为const char类型),第三个发送的数据的长度,

6)关闭套接字closesocket( _In_ SOCKET s );

#define WIN32_LEAN_AND_MEAN
#include<Windows.h>
#include<WinSock2.h>
#include<iostream>
using std::cout;
using std::endl;
int main() {
	WSADATA data;
	WSAStartup(MAKEWORD(2, 2), &data);

	//建立服务端
	//1.创建套接字
	SOCKET sock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//IP地址类型,套接口类型,传输协议类型

	//2.绑定一个port
	sockaddr_in sin = {};//这是一个结构,其中端口和IP地址都需要是网络字节序
	sin.sin_family = AF_INET;
	sin.sin_port = htons(4567);//采用htons
	sin.sin_addr.S_un.S_addr = INADDR_ANY;//绑定默认地址,采用inet_addr
	if (bind(sock, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR) //套接字,指向特定协议地址结构的指针,该地址结构的长度
		cout << "ERROR,绑定端口失败" << endl;
	else cout << "绑定成功" << endl;

	//3.监听端口
	if (listen(sock, 5) == SOCKET_ERROR) cout << "监听失败" << endl;//允许多少用户访问
	else cout << "监听成功" << endl;

	//4.等待客户端连接
	sockaddr_in client = {};
	int nAddrLen = sizeof(sockaddr_in);
	char msg[] = "hello,client";
	while (true) {
		SOCKET cSock = accept(sock, (sockaddr*)(&client), &nAddrLen);//生成新的套接字
		if (cSock == INVALID_SOCKET) cout << "套接字无效" << endl;

		//5.向客户端发送数据
		send(cSock, msg, strlen(msg) + 1, 0);
	}

	//6.关闭自身连接
	closesocket(sock);

	WSACleanup();
}

四、创建客户端
1)创建套接字

2)连接服务器connect( _In_ SOCKET s, _In_reads_bytes_(namelen) const struct sockaddr FAR * name, _In_ int namelen );第一个为套接字,第二个为服务器的协议地址的指针,该地址结构的长度

3)接受服务器信息recv( _In_ SOCKET s, _Out_writes_bytes_to_(len, return) __out_data_source(NETWORK) char FAR * buf, _In_ int len, _In_ int flags );第一个参数为客户端套接字,第二个参数为接受的数据缓冲区char*,第三个为该缓冲区的大小出现错误socket状态为SOCKET_ERROR

4)关闭套接字

#define WIN32_LEAN_AND_MEAN
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<Windows.h>
#include<winSock2.h>
#include<iostream>
using std::cout;
using std::endl;
int main() {
	WSADATA data;
	WSAStartup(MAKEWORD(2, 2), &data);

	//1.创建套接字
	SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sock == INVALID_SOCKET) cout << "套接字建立失败" << endl;
	else cout << "建立成功" << endl;

	//2.连接服务器
	SOCKADDR_IN sin = {};
	sin.sin_family = AF_INET;
	sin.sin_port = htons(4567);//要连接的服务器的端口号
	sin.sin_addr.S_un.S_addr =inet_addr("127.0.0.1");
	if (connect(sock, (sockaddr*)&sin, sizeof(sockaddr)) == SOCKET_ERROR) cout << "连接失败" << endl;
	else cout << "连接成功" << endl;

	//3.接收服务器信息
	char recvbuf[256] = {};
	recv(sock, recvbuf, 256, 0);
	cout << recvbuf <<"接收到"<<endl;
	//4.关闭套接字
	closesocket(sock);
	system("pause");

	WSACleanup();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值