socket单连接(C++)

设计要求:
通过基于socket技术的多机通信程序,实现短消息传递、文件传输。
操作流程:
服务器端编程的步骤:
1:加载套接字库,创建套接字(WSAStartup()/socket());
2:绑定套接字到一个IP地址和一个端口上(bind());
3:将套接字设置为监听模式等待连接请求(listen());
4:请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept());
5:用返回的套接字和客户端进行通信(send()/recv());
6:返回,等待另一连接请求;
7:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。
客户端编程的步骤:
1:加载套接字库,创建套接字(WSAStartup()/socket());
2:向服务器发出连接请求(connect());
3:和服务器端进行通信(send()/recv());
4:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。

服务端:

#pragma warning(disable : 4996)
#include<iostream>
#include<Winsock2.h>
#include<fstream>
#include<string>
#pragma comment(lib, "WS2_32.lib")
using namespace std;

int	server(SOCKET	socket_connect)
{
	cout << "一个用户建立连接" << endl;
	cout << "m:进入发送信息模式" << endl;
	cout << "f:进入发送文件模式" << endl;
	cout << "g:进入接收模式" << endl;
	int judge = 1;
	while (judge)
	{
		char c;
		cin >> c;
		ifstream	ifile;
		char send_message[266];
		char receive_message[266] ;
		receive_message[265] = '\0';
		string	s;

		switch (c)
		{
		case	'm'://发消息
			strcpy(send_message, "#mID:00  ");
			cout << "请输入发送的信息,限256个字符" << endl;
			cin >> send_message + 9;
			send(socket_connect, send_message, sizeof(send_message), 0);
			break;
		case	'f'://发文件
			ifile.open("server_send_data.txt", ios::in);	//文件要求1行不超过256个字符 
			while (getline(ifile, s))
				send(socket_connect, strcat(strcpy(send_message, "#fID:00  "), s.c_str()), sizeof(send_message), 0);
			ifile.close();
			cout << "文件已发出,将文件名为:server_send_data.txt.txt的内容发送" << endl;
			break;
		case	'g'://接收
			recv(socket_connect, receive_message, sizeof(receive_message), 0);
			if (receive_message[0] == '$')
			{
				closesocket(socket_connect);
				judge = 0;
				cout << "用户断开连接," << receive_message + 2 << endl;
			}
			if (receive_message[1] == 'm')
			{
				cout << "收到一条新消息:" << receive_message + 2 << endl;
				send(socket_connect, "#!服务器已收到消息", sizeof("#!服务器已收到消息"), 0);
			}
			if (receive_message[1] == '!')
			{
				cout << "收到客户端反馈:" << receive_message + 2 << endl;
			}
			if (receive_message[1] == 'f')
			{
				ofstream	ofile;
				ofile.open("server_get_data.txt", ios::app);
				ofile << receive_message + 2 << endl;
				ofile.close();
				cout << "收到文件,已写入:server_get_data.txt" << endl;
				send(socket_connect, "#!服务器已收到文件", sizeof("#!服务器已收到文件"), 0);
			}

			break;
		default:
			cout << "输入命令有误,请重新输入" << endl;
		}

	}
	

	return 0;
}


int main()
	{
	cout << "服务端启动" << endl;
	//加载套接字库 
	WSADATA wsaData;
	int result = WSAStartup(MAKEWORD(1, 1), &wsaData);
	if (result != 0)
	{
		cout << "socket库绑定失败,程序终止。" << endl;
		return -1;
	}

	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
	{
		WSACleanup();
		cout << "Socket获取的版本与socket需要的版本不符,程序终止。" << endl;
		return -1;
	}
	//创建套接字	基于IPv4的地址+端口 ,TCP/IP协议
	SOCKET socket_service = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	SOCKADDR_IN socket_service_address;
	socket_service_address.sin_family = AF_INET;
	socket_service_address.sin_port = htons(13000);//字节序转换 

		//将一个点分十进制的IP转换成一个长整数型数
	socket_service_address.sin_addr.s_addr = htonl(INADDR_ANY);
	//	inet_addr("127.0.0.1");  两种选择:1.设置为htonl(INADDR_ANY);INADDR_ANY为本机所有IP,用于多网卡主机  2.设置为具体的IP。
	 
	bind(socket_service, (SOCKADDR*)&socket_service_address, sizeof(SOCKADDR_IN));
	
	listen(socket_service,2);

	//以$开头代表命令	以#开头代表信息  内容中出现 $ # \ 符号时前面需加\号。
	
	SOCKADDR_IN socket_client_address;
	int len = sizeof(SOCKADDR);
	while (1)
	{
	SOCKET socket_connect = accept(socket_service, (SOCKADDR*)&socket_client_address, &len);
	server(socket_connect);
	} 
	WSACleanup();
	return 0;
	 } 

客户端:

#include<iostream>
#include<fstream>
#include <conio.h>
#include<Winsock2.h>
#include<string>
#pragma comment(lib, "WS2_32.lib") 
using namespace std;


/*
1.加载套接字库
2.创建套接字
3.向服务器发出连接请求  
 */
int main()
{
	cout << "客户端启动" << endl;
	//加载套接字库 
	WSADATA wsaData;
	int result= WSAStartup(MAKEWORD(1, 1), &wsaData);
	if (result != 0) 
		{
		cout<< "socket库绑定失败,程序终止。"<<endl;
		return -1;
		}

	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
	{
		WSACleanup();
		cout<<"Socket获取的版本与socket需要的版本不符,程序终止。"<<endl;
		return -1;
	}
	
	
	//创建套接字	基于IPv4的地址+端口 ,TCP/IP协议
	int socket_client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	
	
	//向服务器发出连接请求 
	SOCKADDR_IN address;
	address.sin_family=AF_INET;
	address.sin_port=htons(13000);//字节序转换 
	
		//将一个点分十进制的IP转换成一个长整数型数
	address.sin_addr.s_addr=inet_addr("127.0.0.1"); 
	int i=connect(socket_client,(SOCKADDR*)&address,sizeof(SOCKADDR_IN));
	
	
	if(i!=0)
		cout<<"连接失败"<<endl;
	else
	{
		cout << "套接字初始化成功,可以开始通信。" << endl;
		cout << "m:进入发送信息模式" << endl;
		cout << "f:进入发送文件模式" << endl;
		cout << "g:进入接收模式" << endl;
		cout << "q:断开与服务器连接" << endl;
		int judge = 1;
		while (judge)
		{
			char c;
			cin >> c;
			ifstream	ifile;
			ofstream	ofile;
			char send_message[266];
			char receive_message[266];
			receive_message[265] = '\0';
			string	s;

			switch (c)
			{
			case	'm'://发消息
				strcpy(send_message, "#mID:01  ");
				cout << "请输入发送的信息,限256个字符" << endl;
				cin >> send_message + 9;
				send(socket_client, send_message, sizeof(send_message), 0);
				break;
			case	'f'://发文件
				ifile.open("client_send_data.txt", ios::in);	//文件要求1行不超过256个字符 
				while (getline(ifile, s))
					send(socket_client, strcat(strcpy(send_message, "#fID:01  "), s.c_str()), sizeof(send_message), 0);
				ifile.close();
				cout << "文件已发出,将文件名为:client_send_data.txt的内容发送" << endl;
				break;
			case	'g'://接收
				recv(socket_client, receive_message, sizeof(receive_message), 0);
				if (receive_message[1] == 'm')
				{
					cout << "收到一条新消息:" << receive_message + 2 << endl;
					send(socket_client, "#!客户端已收到消息", sizeof("#!客户端已收到消息"), 0);
				}
				if (receive_message[1] == '!')
				{
					cout << "收到服务端反馈:" << receive_message + 2 << endl;
				}
				if (receive_message[1] == 'f')
				{
					ofile.open("client_get_data.txt", ios::app);
					ofile << receive_message + 2 << endl;
					cout << "收到文件,已写入:client_get_data.txt" << endl;
					send(socket_client, "#!客户端已收到文件", sizeof("#!客户端已收到文件"), 0);
					ofile.close();
				}
				break;

			case	'q'://断开连接
				strcpy(send_message, "#qID:01");
				send(socket_client, send_message, sizeof(send_message), 0);
				closesocket(socket_client);
				judge = 0;
				break;
			default:
				cout << "输入命令有误,请重新输入" << endl;
			}
		}
	}
 	WSACleanup();

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>