小言_互联网的博客

c++ socket服务端(TCP)

549人阅读  评论(0)

上周完成简单收发以及开机自启动,下面测试循环收发double类型的正弦函数。

1. 用一个正弦函数一直发送,接收方为c#客户端

	valarray<double> va1(1000);
	for (int i = 0; i < 1000; i++)
	va1[i] = pi * i / 1000;
	valarray<double> va2(1000);
	va2 = sin(va1);
	while (1)
	{			
		for (int i = 0; i < 1000; i++)
		{
			char buf[50] = { 0 };
			DoubleToString(va2[i], buf);
			cout << buf << endl;
			send(s_accept, (char*)buf, sizeof(buf), 0);
		}
	}

将double转化为string的函数:

DoubleToString.cpp

#define _CRT_SECURE_NO_WARNINGS //strcat不安全
#include "taishang.h"
using namespace std;

void DoubleToString(double data, char buffer[50])
{
	ostringstream oss1;
	oss1 << data;
	//先转化为流,再转换为string, 然后再转换为char
	strcat(buffer, (oss1.str()).c_str());
}

2. 想要收发并行,开启多线程:

先用了pthread.h
a) 解决VS找不到pthread.h
b) 打开VisualStudio2017面板中的项目(Project)
c) 管理NuGet程序包(Manager Nuget Package )
d) 打开浏览(Browse)一栏,
e) 在搜索栏搜索pthread,
f) 安装(install)

void* send_data(void* args)
{
cout << “SendData!” << endl;
return 0;
}
pthread_t SendData;
pthread_create(&SendData, NULL, send_data, NULL);

错误 2 error LNK2019: 无法解析的外部符号 __imp__pthread_create,该符号在函数 _main 中被引用。
加入#pragma comment(lib, “pthreadVC2.lib”)之后显示无法打开pthreadVC2.lib

下载 pthreads-w32-2-8-0-release.exe之后解压缩:打开Pre-built.2文件夹,分别复制include文件夹和lib文件夹中的文件到VS安装目录下的\VC\include文件夹和\VC\lib文件夹中或VC6.0安装目录下的\VC98\include文件夹和\VC 98\lib文件夹中。
运行发现计算机还是无法找到pthreadVC2.dll。
将Pre-built.2—>lib文件夹里的pthreadVC2.dll复制到C:\Windows\SysWOW64中(64位系统)

换用#include ,但是这个头文件里也有bind函数,和winsock.h里的冲突了。未解决
温老师说库冲突只能链接一个,不能用命名空间之类指定,可以改称成c用winsock,也可以用C++的Socket类(纯c++用法,Csocket类和C同步socket类),不用API。但是winsock用的多。


发送数据是1000个sleep(100)。
时间长会把网络助手卡住,自己的程序不卡。

3. 收到的数据存储:

#include  <ostream>
#include  <fstream>
ofstream fdata;
fdata.open("D:\\五自由度\\taishang_serve\\taishang_serve.txt", ios::app); //从文件末尾开始写
fdata << msg  << endl;
fdata.close(); 


主程序

#include <iostream>
#include <winsock.h>
#include <math.h>
#include <pthread.h>
#include <math.h>
#include <valarray>
#include <ostream>
#include <fstream>
#include "taishang.h"

#pragma comment(lib, "pthreadVC2.lib")
#pragma comment(lib,"ws2_32.lib")
using namespace std;

//全局变量线程才能使用
ofstream fdata;
SOCKET s_sock;
SOCKADDR_IN server_addr;
SOCKADDR_IN client_addr;
SOCKET s_accept;
WSADATA wsaData;
WORD wVersion;
double pi = 3.14159265359;

void* send_data(void* args)
{
	cout << "SendData!" << endl;
	
	valarray<double> va1(1000);
	for (int i = 0; i < 1000; i++)
		va1[i] = pi * i / 1000;
	valarray<double> va2(1000);
	va2 = sin(va1);
	while (1)
	{
	for (int i = 0; i < 1000; i++)
		{
			char buf[50] = { 0 };
			DoubleToString(va2[i], buf);
			//cout << buf << endl;
			int m = send(s_accept, (char*)buf, sizeof(buf), 0);
		}
	Sleep(100);
	}
	
	return 0;
}

void* recv_data(void* args)
{
	cout << "RecvData!" << endl;
	while (1)
	{
		char msg[1024];
		int res = recv(s_accept, msg, 1024, 0);
		if (res == -1)
		{
			cout << "接收失败" << endl;
			break;
		}
		else if (msg != 0)
		{
			msg[res] = '\0';
			fdata.open("D:\\五自由度\\taishang_serve\\taishang_serve.txt", ios::app); //从文件末尾开始写
			fdata << msg  << endl;
			fdata.close(); 
			cout << msg << endl;
		}

	}
	return 0;
}


int main(int argc, char **argv)
{
	// 初始化套接字动态库
	int a = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (a != 0)
	{
		cout << "初始化套接字库失败" << endl;
		return -1;
	}
	// 创建服务器套接字 
	s_sock = socket(AF_INET, SOCK_STREAM, 0);
	if (INVALID_SOCKET == s_sock)
	{
		cout << "初始化套接字库失败" << endl;
		return -2;
	}
	//初始化服务器套接字
	server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");//服务端台上IP,给自己发
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(8888);

	//绑定
	int s_bind = bind(s_sock, (LPSOCKADDR)&server_addr, sizeof(SOCKADDR_IN));
	if (s_bind == SOCKET_ERROR)
	{
		cout << "绑定失败" << endl;
		return -3;
	}

	//监听
	int s_lis = listen(s_sock, 5);
	if (s_lis != 0)
	{
		cout << "监听失败" << endl;
		return -4;
	}

	int len1 = sizeof(SOCKADDR_IN);
	s_accept = accept(s_sock, (SOCKADDR *)&client_addr, &len1);
	if (s_accept == SOCKET_ERROR)
	{
		cout << "连接失败" << endl;
		return -5;
	}

	UCHAR c1[] = { "Hello Client!" };
	int m = send(s_accept, (char*)c1, sizeof(c1), 0); //TCP
	if (m == SOCKET_ERROR)
	{
		cout << "发送失败" << endl;
		return -6;
	}
	cout << "连接成功" << endl;
	
	//开启发数线程
	pthread_t SendData;
	pthread_create(&SendData, NULL, send_data, NULL);

	//开启收数线程
	pthread_t RecvData;
	pthread_create(&SendData, NULL, recv_data, NULL);

	system("pause");
	return 0;
}


转载:https://blog.csdn.net/Sunshine_axin/article/details/101634199
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场