C++ Java分别作服务器与客户端实现TCP数据收发

Java模块

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.Socket;

public class JavaClient{
	public static void main(String [] args) throws InterruptedException, IOException
	{
		InetSocketAddress addr = new InetSocketAddress("192.168.0.149", 5678); //创建socket
		Socket sock = new Socket();  
		sock.connect(addr);//连接服务器
		BufferedReader is = null;
		PrintWriter os = null;

		os = new PrintWriter(sock.getOutputStream()); //管道的写工具
		is = new BufferedReader(new InputStreamReader(sock.getInputStream()));  //管道的读工具

		BufferedReader user = new BufferedReader(new InputStreamReader(System.in)); //从控制台读取命令的工具
		System.out.print("client say:");
		String msg = user.readLine();

		while(!msg .equals("bye"))
		{
			os.println(msg);
			os.flush();

			
			String echo = is.readLine();
			System.out.println(echo);			
			

			System.out.print("client say:");
			msg = user.readLine();
		}

		os.close();
		is.close();
		sock.close();	
	}	
}

C++(单个client)

#include <winsock2.h>
#include <process.h>
#include <iostream>
#pragma comment(lib, "ws2_32.lib")
#include <list>

using namespace std;
std::list<SOCKET> client_list;

char szMsg[0x1000] = "";
char szEcho[0x1000] = "";
int acceptData;

int main()
{
	//cout << "1";
	// WSADATA为一种数据结构。用来存储被WSAStartup函数调用后返回的Windows Sockets数据
	WSADATA wsadata;
	// 是为了向操作系统说明我们用的库文件种类
	WSAStartup(0x22, &wsadata);

	unsigned short sPort = 5678;

	
	int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	sockaddr_in saddr;
	saddr.sin_addr.s_addr = ADDR_ANY;
	saddr.sin_port = htons(sPort);
	saddr.sin_family = AF_INET;
	bind(sockfd, (const sockaddr*)(&saddr), sizeof(saddr));
	listen(sockfd, 3);
	cout << "waiting for client to connect, port:5678......" << endl;

	//caddr为客户端id
	sockaddr_in caddr;
	int caddr_len = sizeof(caddr);
	int client = accept(sockfd, (sockaddr*)&caddr, &caddr_len);

	//pAddr为客户端ip地址,ntohs(caddr.sin_port)为客户端线程?
	unsigned char *pAddr = (unsigned char*)&caddr.sin_addr.s_addr;
	cout << (int)pAddr[0] << "." << (int)pAddr[1] << "." << (int)pAddr[2] << "." << (int)pAddr[3] 
		<< ":" << (int)ntohs(caddr.sin_port) << "." << "coming" << endl;
	

	getpeername(client, (sockaddr*)&caddr, &caddr_len);	// 获取当前连接的客户端的IP地址和端口号

	for (;;)
	{
		acceptData = recv(client, szMsg, sizeof(szMsg) - 1, 0);
		// 当缓冲区无客户端发送的信息时,acceptData=-1
		if (0 >= acceptData)
		{
			cout << "客户端已关闭" << endl;
			closesocket(client);
			break;
		}

		//接受缓冲区数据szMsg
	
		cout << "client Say:" << szMsg << endl;

		//发送数据szEcho
		memcpy(szEcho, szMsg, size(szMsg));
		cout << "szEcho: " << szEcho;
		send(client, szEcho, strlen(szEcho), 0);
	}

	while (1);
	return 0;
}

多个client

// ConsoleServer.cpp : 定义控制台应用程序的入口点。

#include <winsock2.h>
#include <process.h>
#pragma comment(lib, "ws2_32.lib")
#include <list>
#include <iostream>


std::list<SOCKET> client_list;
using namespace std;

void thread_client(void *);

int main(int argc, char * argv[])
{
	WSADATA wsadata;
	WSAStartup(0x22, &wsadata);
	unsigned short sPort = argc > 1 ? atoi(argv[1]) : 5678;
	int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sockfd == INVALID_SOCKET)
	{
		printf("fail to create socket.\n");
		return 1;
	}

	sockaddr_in saddr;
	saddr.sin_addr.s_addr = ADDR_ANY;
	saddr.sin_port = htons(sPort);
	saddr.sin_family = AF_INET;
	if (bind(sockfd, (const sockaddr *)(&saddr), sizeof(saddr)))
	{
		printf("fail to bind, errno: %d.\n", GetLastError());
		DWORD dw = WSAGetLastError();
		return 2;
	}


	if (listen(sockfd, 5))
	{
		printf("fail to listen.\n");
		return 3;
	}

	printf("Server is listening at [%d].\n"
		"Wating for client to connect...\n"
		, sPort);

	for (;;)
	{
		sockaddr_in caddr;
		int caddr_len = sizeof(caddr);
		int client = accept(sockfd, (sockaddr *)&caddr, &caddr_len);
		unsigned char * pAddr = (unsigned char *)&caddr.sin_addr.s_addr;

		printf("[%d.%d.%d.%d : %d] coming.\n", pAddr[0], pAddr[1], pAddr[2], pAddr[3], ntohs(caddr.sin_port));


		_beginthread(thread_client, 0, (void *)client);

		client_list.push_back(client);

	}
	return 0;
}

void thread_client(void * args)
{
	SOCKET client = (int)args;
	sockaddr_in caddr;
	int caddr_len = sizeof(caddr);
	getpeername(client, (sockaddr *)&caddr, &caddr_len);
	unsigned char * pAddr = (unsigned char *)&caddr.sin_addr.s_addr;
	unsigned short usPort = ntohs(caddr.sin_port);

	for (;;)
	{
		char szMsg[0x1000] = "";
		if (0 >= recv(client, szMsg, sizeof(szMsg) - 1, 0))
			break;




		//控制台输出java传输过去的内容
		cout << szMsg;

		
		//发送信息到java端

		char szEcho[0x1000] = "";
		//给szEcho赋值
		sprintf(szEcho, "Server Say: [%d.%d.%d.%d:%d] %s"
			, pAddr[0], pAddr[1], pAddr[2], pAddr[3]
			, usPort
			, szMsg);

		for (std::list<SOCKET>::iterator it = client_list.begin();
			it != client_list.end();
			it++)
		{
			send(*it, szEcho, strlen(szEcho), 0);

		}
		
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值