windows下socket编程实现client和server双向通信

服务端代码server.c

// server.cpp : Defines the entry point for the console application.
//

#include <stdio.h>
#include <Winsock2.h>	//Socket的函数调用 
#include <windows.h>

#define BUF_SIZE 6400  //  缓冲区大小 

#pragma comment (lib, "ws2_32")		// 使用WINSOCK2.H时,则需要库文件WS2_32.LIB

DWORD WINAPI Rcv( LPVOID lpParam )
{
	SOCKET sClient = *(SOCKET*)lpParam;
	int retVal;
	char bufRecv[BUF_SIZE];
	memset( bufRecv, 0, sizeof( bufRecv ) );
	while(1)
	{
		retVal = recv( sClient, bufRecv, BUF_SIZE, 0 );
		if ( retVal == SOCKET_ERROR ) {
			printf( "recive faild!\n" );
			break;
		} else {
			printf( "收到客户端消息:%s\n", bufRecv );
		}
	}
	return 0;
}

DWORD WINAPI Snd( LPVOID lpParam )
{
	SOCKET sClient = *(SOCKET*)lpParam;
	int retVal;
	char bufSend[BUF_SIZE];
	memset( bufSend, 0, sizeof( bufSend ) );
	while(1)
	{
		gets( bufSend );
		retVal = send( sClient, bufSend, strlen(bufSend)+sizeof(char), 0 );
		if ( retVal == SOCKET_ERROR ) {
			printf( "send faild!\n" );
			break;
		}
	}
	return 0;
}

int main(int argc, char* argv[])
{
	// 初始化套接字动态库
	WSADATA wsaData;
	if ( WSAStartup(MAKEWORD(2, 2), &wsaData) != 0 ) {
		printf( "winsock load faild!\n" );
		return 1;
	}

	//  创建服务段套接字
	SOCKET sServer = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
	if ( sServer == INVALID_SOCKET ) {
		printf( "socket faild!\n" );
		WSACleanup();
		return -1;
	}

	//  服务端地址
	sockaddr_in addrServ;

	addrServ.sin_family = AF_INET;
	addrServ.sin_port = htons( 9999 );
	addrServ.sin_addr.s_addr = htonl( INADDR_ANY ); 

	//  绑定套接字
	if ( bind( sServer, ( const struct sockaddr* )&addrServ, sizeof(addrServ) ) == SOCKET_ERROR ) {
		printf( "bind faild!\n" );
		closesocket( sServer );
		WSACleanup();
		return -1;
	} 

	printf("Server is On IP:[%s],port:[%d]\n",inet_ntoa(addrServ.sin_addr),ntohs(addrServ.sin_port)); 

	//  监听套接字  数字表示最多能监听客户个数
	if ( listen( sServer, 5 ) == SOCKET_ERROR ) {
		printf( "listen faild!\n" );
		closesocket( sServer );
		WSACleanup();
		return -1;
	} 

	SOCKET sClient; //  客户端套接字

	sockaddr_in addrClient;
	int addrClientLen = sizeof( addrClient );

	sClient = accept( sServer, ( sockaddr FAR* )&addrClient, &addrClientLen );
	if ( sClient == INVALID_SOCKET ) {
		printf( "accept faild!\n" );
		closesocket( sServer );
		WSACleanup();
		return -1;
	}
	printf("accepted client IP:[%s],port:[%d]\n",inet_ntoa(addrClient.sin_addr),ntohs(addrClient.sin_port));

	HANDLE hThread1, hThread2;
	DWORD dwThreadId1, dwThreadId2;

	hThread1 = ::CreateThread(NULL, NULL, Snd, (LPVOID*)&sClient, 0, &dwThreadId1);
	hThread2 = ::CreateThread(NULL, NULL, Rcv, (LPVOID*)&sClient, 0, &dwThreadId2);

	::WaitForSingleObject(hThread1, INFINITE);
	::WaitForSingleObject(hThread2, INFINITE);
	::CloseHandle(hThread1);
	::CloseHandle(hThread2);

	closesocket( sClient );
	WSACleanup(); // 资源释放

	return 0;
}

客户端代码client.c

// client.cpp : Defines the entry point for the console application.
//

#include <stdio.h>
#include <Winsock2.h>	//Socket的函数调用 
#include <windows.h>

#define BUF_SIZE 6400

#pragma comment (lib, "ws2_32")		// 使用WINSOCK2.H时,则需要库文件WS2_32.LIB

DWORD WINAPI Rcv( LPVOID lpParam )
{
	SOCKET sHost = *(SOCKET*)lpParam;
	int retVal;
	char bufRecv[BUF_SIZE];
	memset( bufRecv, 0, sizeof( bufRecv ) );
	while(1)
	{
		retVal = recv( sHost, bufRecv, BUF_SIZE, 0 );
		if ( retVal == SOCKET_ERROR ) {
			printf( "recive faild!\n" );
			break;
		} else {
			printf( "收到服务器消息:%s\n", bufRecv );
		}
	}
	return 0;
}

DWORD WINAPI Snd( LPVOID lpParam )
{
	SOCKET sHost = *(SOCKET*)lpParam;
	int retVal;
	char bufSend[BUF_SIZE];
	memset( bufSend, 0, sizeof( bufSend ) );
	while(1)
	{
		gets( bufSend );
		retVal = send( sHost, bufSend, strlen(bufSend)+sizeof(char), 0 );
		if ( retVal == SOCKET_ERROR ) {
			printf( "send faild!\n" );
			break;
		}
	}
	return 0;
}

int main(int argc, char* argv[])
{
	WSADATA wsaData;
	if ( WSAStartup( MAKEWORD(2,2), &wsaData ) != 0 ) {
		printf( "Winsock load faild!\n" );
		return 1;
	}

	//  服务器套接字
	SOCKET sHost = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
	if ( sHost == INVALID_SOCKET ) {
		printf( "socket faild!\n" );
		WSACleanup();
		return -1;
	}

	SOCKADDR_IN servAddr;
	servAddr.sin_family = AF_INET;
	//  注意   当把客户端程序发到别人的电脑时 此处IP需改为服务器所在电脑的IP
	servAddr.sin_addr.S_un.S_addr = inet_addr( "127.0.0.1" );
	servAddr.sin_port = htons( 9999 );

	//  连接服务器
	if ( connect( sHost, (LPSOCKADDR)&servAddr, sizeof( servAddr ) ) == SOCKET_ERROR ) {
		printf( "connect faild!\n" );
		closesocket(sHost);
		WSACleanup();
		return -1;
	}
	printf("连接到服务器 IP:[%s],port:[%d]\n",inet_ntoa(servAddr.sin_addr),ntohs(servAddr.sin_port));

	HANDLE hThread1, hThread2;
	DWORD dwThreadId1, dwThreadId2;

	hThread1 = ::CreateThread( NULL, NULL, Snd, (LPVOID)&sHost, 0, &dwThreadId1 );
	hThread2 = ::CreateThread( NULL, NULL, Rcv, (LPVOID)&sHost, 0, &dwThreadId2 );

	::WaitForSingleObject( hThread1, INFINITE );
	::WaitForSingleObject( hThread2, INFINITE );
	::CloseHandle(hThread1);
	::CloseHandle(hThread2);

	closesocket(sHost);
	WSACleanup();
	return 0;
}

截图如下:编译好后首先是启动服务端(来监听),然后再启动客户端

原文地址:https://www.cnblogs.com/wuyepeng/p/9726844.html

时间: 2024-11-09 00:39:49

windows下socket编程实现client和server双向通信的相关文章

【网络】Windows 下 socket 编程范例

1 #include "winsock2.h" 2 #include <stdint.h> 3 #include <stdio.h> 4 5 #include <ctype.h> 6 #include <time.h> 7 8 #define MAX_BUF_LEN 1024 9 10 #define ERR (-1) 11 #define OK 0 12 13 enum { 14 TCP = 6, 15 UDP = 17, 16 };

windows下socket编程小例子

服务端 首先引进头文件winsock2.h和库文件ws2_32.lib(开发环境为vs2015) 加载套接字库和创建套接字 绑定套接字到一个IP地址和端口上 监听客户端发来的连接请求 接收或发送信息 关闭套接字,套接字库 客户端 首先引进头文件winsock2.h和库文件ws2_32.lib(开发环境为vs2015) 加载套接字库,创建套接字对象 向服务端发出连接请求 收发信息 关闭套接字和套接字库 注释 WSAStartup结构体中主要包含了系统所支持的Winsock版本信息 WSAstart

Linux下socket编程,附带tcp例子

1.网络中进程之间如何通信? 本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类: 消息传递(管道.FIFO.消息队列) 同步(互斥量.条件变量.读写锁.文件和写记录锁.信号量) 共享内存(匿名的和具名的) 远程过程调用(Solaris门和Sun RPC) 但这些都不是本文的主题!我们要讨论的是网络中进程之间如何通信?首要解决的问题是如何唯一标识一个进程,否则通信无从谈起!在本地可以通过进程PID来唯一标识一个进程,但是在网络中这是行不通的.其实TCP/IP协议族已经帮我们解决了这个问

Linux下Socket编程

http://blog.chinaunix.net/uid-20733992-id-3450058.html 原文地址:Linux下Socket编程 作者:yulianliu1218 Linux下Socket编程 什么是Socket Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序.要学Internet上的TCP/IP网络编程,必须理解Socket接口. Socket接口设计者最先是将接口放在Unix操作系统里面

初探WINDOWS下IME编程

初探WINDOWS下IME编程作者:广东南海市昭信科技有限公司-李建国 大家知道,DELPHI许多控件有IME属性.这么好用的东西VC可没自带,怎么办呢?其实,可通过注册表,用API实现.下面说一下本人对IME的研究结果,并提供示例工程供大家参考: 下载示例工程 10.6K 本文示例程序运行结果如上图1.将用到的API RegOpenKey:打开注册表一键RegQueryValue:查询一键值RegQueryValueEx:同上RegCloseKey:关闭打开的键 LoadKeyboardLay

Linux下Socket编程的端口问题( Bind error: Address already in use )

Linux下Socket编程的端口问题( Bind error: Address already in use ) 在进行linux网络编程时,每次修改了源代码并再次编译运行时,常遇到下面的地使用错误: Bind error: Address already in use 虽然用Ctrl+C强制结束了进程,但错误依然存在,用netstat -an |grep 5120和ps aux |grep 5120都还能看到刚才用Ctrl+C“强制结束”了的进程,端口还是使用中,只好每次用kill结束进程,

Windows 下用 gogs 配置局域网 git server

大道曙光 Windows 下用 gogs 配置局域网 git server 最近要用 C# 开发一个新的项目,所以需要在 Windows 局域网环境下构建一个 git server. 在 Windows 7 上搭建 git server 的方案很多.比如: 1. gogs 2. bamboo(https://www.atlassian.com/software/bamboo/) 3. Github for Windows + CoqSSH(https://github.com/msysgit/m

Linux下socket编程基本知识

本文档主要讲解了Linux下socket编程的一些基本知识,主要包括套接字和字节序的概念,以及一些常用的结构体和函数. 本文是在网易云课堂学习过程中的记录,这个老师讲得很不错,推荐大家围观. Linux网络编程 Linux网络编程|人工智能物联网 1.概念 1.1套接字(socket) Socket(套接字)是一种通讯机制,它包含一整套的调用接口和数据结构的定义,它给应用进程提供了使用如TCP/UDP等网络协议进行网络通讯的手段. Linux中的网络编程通过socket接口实现,socket既是

一个linux下socket编程的例子,client连server

关于socket编程,以下文章写得比较好:http://www.cnblogs.com/xudong-bupt/archive/2013/12/29/3483059.html 1. accept()函数,如果客户端一直没有连接,则服务端阻塞在accept()函数处. 以下是client代码 //============================================================================ // Name : client.cpp // A