我是靠谱客的博主 唠叨丝袜,最近开发中收集的这篇文章主要介绍c语言实现socket 多线程 并行,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

服务端

#if 1
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<iostream>
#include<WinSock2.h>
#include <ws2tcpip.h>
#include <conio.h>
#include <cstdio>
#include<windows.h>
#pragma warning(disable: 4996)
#pragma comment(lib, "ws2_32.lib")
using namespace std;

#define MaxBufSize 1024
void Menu();
int x = 0;
DWORD WINAPI Server_send(LPVOID IpParameter);
DWORD WINAPI Clinet_recv(LPVOID IpParameter) {
	char RecvBuf[MaxBufSize] = "";
	SOCKET *Client_recv = (SOCKET *)IpParameter;
	HANDLE Server_send_del = CreateThread(NULL, 0, &Server_send, Client_recv, 0, NULL);
	while (true) {
		if (recv(*Client_recv, RecvBuf, MaxBufSize, 0) > 0) {
			if (!strcmp(RecvBuf, "bye") || !strcmp(RecvBuf, "再见") || !strcmp(RecvBuf, "quit")) {
				
				break;
				
			}
			cout << "接收到的消息是:" << RecvBuf << "            来自客户端:" << *Client_recv << endl;
			memset(RecvBuf, 0, sizeof(RecvBuf));
		}
	}
	closesocket(*Client_recv);
	CloseHandle(Server_send_del);
	x = *Client_recv;
	cout << "客户端 "<< *Client_recv <<" 断开连接" << endl;
	return 0;
}

DWORD WINAPI Server_send(LPVOID IpParameter) {

	char SendBuf[MaxBufSize] = "", info[1024];
	SOCKET *Serve_send = (SOCKET*)IpParameter;

	while (true) {
		
		cin >> info;
		if (x == *Serve_send)
			break;
		if (x == -1) {
			cout << "断开连接" << endl;
			closesocket(*Serve_send);
			return 0;
		}
		strcat(SendBuf, info);
		memset(info, 0, sizeof(info));
		cout << "向客户端 " << *Serve_send << " 发送消息" << endl;
		if (send(*Serve_send, SendBuf, MaxBufSize, 0) < 0) {
			
			cout << "发送失败" << endl;

		}
		memset(SendBuf, 0, sizeof(SendBuf));
	}
	closesocket(*Serve_send);
	return 0;
}

void Stop(SOCKET &sockSER) {
	closesocket(sockSER);
	WSACleanup();
	cout << "服务器已关闭" << endl;
}

void start(SOCKET & socketSER) {
	WSADATA wsadata;  //一种数据结构。这个结构被用来存储被WSAStartup函数调用后返回的Windows Sockets数据。它包含Winsock.dll执行的数据。
	sockaddr_in addrServer;
	if (WSAStartup(MAKEWORD(2, 2), &wsadata))
		exit(0);
	socketSER = socket(AF_INET, SOCK_STREAM, 0);
	addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	addrServer.sin_family = AF_INET;
	addrServer.sin_port = htons(7000);
	if (bind(socketSER, (SOCKADDR*)&addrServer, sizeof(SOCKADDR)) == SOCKET_ERROR) {
		cout << "端口绑定错误";
		exit(-1);
	}
	else
		cout << "端口绑定成功" << endl;
	if (listen(socketSER, 10)) {
		cout << "失败" << endl;
		exit(-1);
	}
	else
		cout << "监听成功n等待客户端发起连接" << endl;
}

int accept_Clien(SOCKET &sockSER) {

	while (true) {
		sockaddr_in addrClient;
		SOCKET *serClien = new SOCKET;
		int len = sizeof(SOCKADDR);
		*serClien = accept(sockSER, (SOCKADDR *) &addrClient, 0);
		cout << "客户端已连接到服务器,ip是:" << inet_ntoa(addrClient.sin_addr) << "  句柄值是" << *serClien << endl;
		if (*serClien == -1) {
			cout << "连接失败" << endl;

		}
	
		CreateThread(NULL, 0, &Clinet_recv, serClien, 0, NULL);
	}
	return 0;

}
void Menu() {
	printf("------网络通信服务器端------n");
	printf("1、启动服务器n2、开始接受客户端连接n3、关闭服务器n4、返回主菜单n5、退出系统n可进行多客户端通信n");
}
int main(int argc, char ** argv) {
	SOCKET socketSER;
	int Choose;
	Menu();
	while (true) {
		if (x == -1) {
			cout << x;
		}
		cin >> Choose;
		switch (Choose) {
		case 1:
			start(socketSER);
			break;
		case 2:
			accept_Clien(socketSER);
			break;
		case 3:
			Stop(socketSER);
			break;
		case 5:
			exit(0);
			break;
		case 4:
			system("cls");
			Menu();
			break;
		default:
			printf("输入错误!!请重新输入。n");

		}
	}
}
#endif

客户端

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include<string>
#include<WinSock2.h>
#pragma warning(disable:4996)
#pragma comment (lib,"ws2_32.lib")
using namespace std;
const int PORT = 7000;
#define MaxBufSize 1024
#define _CRT_SECURE_NO_WARINGS


//监听来自服务器的消息
DWORD WINAPI  recvFromServer(LPVOID lpParameter)
{
	char RecvBuf[MaxBufSize];
	
	SOCKET *ClientSocket = (SOCKET*)lpParameter;
	while (true) {
		memset(RecvBuf, '', sizeof(RecvBuf));
		if (recv(*ClientSocket, RecvBuf, MaxBufSize, 0) > 0) {
			
			std::cout << "自服务器接收到信息  " << RecvBuf << "n";
		}
		
	}
	return 0;
}
void Stop(SOCKET &SocketClient) {
	closesocket(SocketClient);
	WSACleanup();
	std::cout << "客户机关闭" << std::endl;
}
int Start(SOCKET &SocketClient) {
	WSADATA wsd;
	WSAStartup(MAKEWORD(2, 2), &wsd);
	SocketClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	SOCKADDR_IN  ClientAddr;

	ClientAddr.sin_family = AF_INET;
	ClientAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	ClientAddr.sin_port = htons(PORT);
	int n = 0;
	n = connect(SocketClient, (struct sockaddr*)&ClientAddr, sizeof(ClientAddr));
	if (n == SOCKET_ERROR) {
		cout << "连接失败" << endl;
		return -1;
	}
	cout << "已经连接到服务器" << endl;
	return 0;
}
void Client_send(SOCKET &SocketClient) {
	CreateThread(NULL, 0, &recvFromServer, &SocketClient, 0, NULL);
	char info[1024], SendBuff[MaxBufSize] = "";
	cout << "请输入要发送的信息,按回车结束发送:" << endl;
	while (1) {
	
		cin >> info;
		strcat(SendBuff, info);
		memset(info, 0, sizeof(info));

		 send(SocketClient, SendBuff, sizeof(SendBuff), 0);
		if (!strcmp(SendBuff, "bye") || !strcmp(SendBuff, "再见") || !strcmp(SendBuff, "quit"))
		{
			system("cls");
			Stop(SocketClient);
			break;
		}
		memset(SendBuff, 0, sizeof(SendBuff));
	}
	closesocket(SocketClient);
	WSACleanup();
}
void Menu() {
	cout << "1、启动客户机n2、开始对话n3、关闭客户机 n4、打开菜单n" << endl;
}
int main() {
	SOCKET SocketClient;
	int Choose;
	Menu();
	while (true) {
		cin >> Choose;
		switch (Choose) {
		case 1:
			Start(SocketClient);
			break;
		case 2:
			Client_send(SocketClient);
			break;
		case 3:
			Stop(SocketClient);
			exit(0);
			break;
		case 4:
			system("cls");
			Menu();
			break;
		default:
			printf("输入错误!!请重新输入。n");

		}
	}
	
	return 0;
}


因为线程回调的问题我没有搞清楚,所以服务端的断开连接没有做。只能是客户端断开,我使用句柄值标记客户机,而不是ip。因为这是一个本机的模拟tcp通信的简陋黑框互动,会有回环地址的问题。

代码思路非常简单,服务端创建一个socket接受客户端连接请求。服务端中创建一个接受线程,在接受线程中创建一个发送线程。
客户端创建一个接受线程。

最后

以上就是唠叨丝袜为你收集整理的c语言实现socket 多线程 并行的全部内容,希望文章能够帮你解决c语言实现socket 多线程 并行所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(36)

评论列表共有 0 条评论

立即
投稿
返回
顶部