流式套接字实现简单的客户端/服务端通信过程
来源:互联网 发布:天地图数据融合 编辑:程序博客网 时间:2024/06/07 03:46
一、 实验内容
- 熟悉流式套接字socket函数的使用方法,包括建立连接、数据发送/接收和关闭连接等;
- 客户端可向服务端发送任意字符串,服务端在接收到该字 符串后,回送给客户端;(此过程可循环)
- 服务端在接收到新连接后,能够打印出客户端的ip和端口;(如何获取连接套接字上的地址信息,请自行查阅资料)
- 服务端采用多线程模式,能够同时接收多个客户端的连接请求,为每个客户端连接开启一个线程;(多线程编程自行查阅资料)
二、 实验要求
提交源码(源码编写要规范)、可执行程序、实验报告(要有程序运行截图)。
基本知识:
SOCKET socket(int af,// 目前只提供PF_INET(AF_INET)int type,// Socket的类型(SOCK_STREAM、SOCK_DGRAM)int protocol,// 通讯协议(如果使用者不指定,则设为0));
bind( _In_ SOCKET s,// Socket对象名 _In_reads_bytes_(namelen) const struct sockaddr FAR * name,//结构体 Socket的地址值,即所在及其的IP地址 _In_ int namelen ); //调用bind()函数之后,为socket()函数创建的套接字关联一个相应地址,发送到这个地址
int listen(SOCKET s,// 需要建立监听的Socketint backlog,// 最大连接个数);
accept( _In_ SOCKET s, _Out_writes_bytes_opt_(*addrlen) struct sockaddr FAR * addr, _Inout_opt_ int FAR * addrlen );
int recv(SOCKET s,// Socket的识别码char FAR *buf,// 存放接收到的数据的缓存区int len,// buf的长度int flags// 此函数被调用的方式);int send(SOCKET s,// Socket的识别码const char FAR *buf,// 存放要传送的数据的缓存区int len, // buf的长度int flags// 此函数被调用的方式);
CreateThread( _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ SIZE_T dwStackSize, _In_ LPTHREAD_START_ROUTINE lpStartAddress,加载函数地址 _In_opt_ __drv_aliasesMem LPVOID lpParameter,加载函数参数 _In_ DWORD dwCreationFlags, _Out_opt_ LPDWORD lpThreadId );
connect( _In_ SOCKET s, _In_reads_bytes_(namelen) const struct sockaddr FAR * name, _In_ int namelen );
int recv(SOCKET s, // Socket的识别码char FAR *buf, // 存放接收到的数据的缓存区int len, // buf的长度int flags // 此函数被调用的方式);int send(SOCKET s,// Socket的识别码const char FAR *buf,// 存放要传送的数据的缓存区int len, // buf的长度int flags// 此函数被调用的方式);
编译器报错C4996:
(1)使用VS提供的 编译器选择性提供warning功能
使用 #pragma warning( disable :4996) 即可消除。
(2) 设置预处理选项:a. Projectproperties->ConfigurationProperties->C/C++->Preprocessor->Preprocessor Definitionsb.
点击按钮(...)c. 输入:_CRT_SECURE_NO_WARNINGS。
注:使用 "\n" 相隔
(3)在引用库文件开头写一个宏定义
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
源码
server
#include<iostream>#include<winsock2.h>#pragma comment(lib, "ws2_32.lib")#define IP_ADDRESS "127.0.0.1"#define PORT 4445#pragma warning(disable:4996)using namespace std;DWORD WINAPI ClientThread(LPVOID lpParameter){SOCKET ClientSocket = (SOCKET)lpParameter;sockaddr_in ClientAddr;int Len = sizeof(ClientAddr);char RecvBuffer[MAX_PATH];int Ret = 0;while (true) {memset(RecvBuffer, 0x00,sizeof(RecvBuffer));Ret = recv(ClientSocket, RecvBuffer, MAX_PATH, 0);getpeername(ClientSocket,(struct sockaddr *)&ClientAddr,&Len);if (Ret == SOCKET_ERROR || Ret ==0){cout << "Client "<<inet_ntoa(ClientAddr.sin_addr) <<":"<<ClientAddr.sin_port<<" Exit!"<<endl;break;}cout << "Client " << inet_ntoa(ClientAddr.sin_addr) << ":" << ClientAddr.sin_port << " connect" << endl;cout << "receive" << " message:" << RecvBuffer<<endl;send(ClientSocket, RecvBuffer, MAX_PATH, 0);}return 0;}int main(int argc, char * argv[]){WSADATA Ws;SOCKET ClientSocket,ServerSocket;struct sockaddr_in ClientAddr,ServerAddr;int Ret = 0;int Len = 0;HANDLE hThread = NULL;if (WSAStartup(MAKEWORD(2, 2), &Ws) != 0){cout << "Windows Init Error " << GetLastError() << endl;return - 1;}ServerAddr.sin_family = AF_INET;ServerAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);ServerAddr.sin_port = htons(PORT);memset(ServerAddr.sin_zero,0x00,8);//create socketServerSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if (ServerSocket == INVALID_SOCKET){cout << "create socket Error::" << endl;return -1;}//bindRet = bind(ServerSocket,(struct sockaddr *)&ServerAddr,sizeof(ServerAddr));if (Ret != 0){cout << "bind Error::" << GetLastError() << endl;return -1;}Ret = listen(ServerSocket, 5);if (Ret != 0){cout << "listen Error::" << GetLastError() << endl;return -1;}cout << "server is up" << endl;//接受数据while (true){Len = sizeof(ClientSocket);ClientSocket = accept(ServerSocket,(struct sockaddr *)&ClientAddr,&Len);if(ClientSocket == INVALID_SOCKET){cout << "accept Error" << GetLastError() << endl;return -1;}hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)ClientSocket, 0, NULL);if (hThread == NULL){cout << "create hthread Error::" << endl;break;}CloseHandle(hThread);}closesocket(ClientSocket);closesocket(ServerSocket);WSACleanup();return 0;}
Client:
#include<iostream>#include<winsock2.h>#pragma comment(lib,"ws2_32.lib")#define IP_ADDRESS "127.0.0.1"#define PORT 4445#pragma warning(disable:4996)using namespace std;int main(int argc, char *argv[]){WSADATA Ws;SOCKET ClientSocket;int Ret = 0;char SendBuffer[MAX_PATH];char RecvBuffer[MAX_PATH];if (WSAStartup(MAKEWORD(2, 2), &Ws) != 0){cout << "Windows Init Error::" << GetLastError() << endl;return -1;}//create socketClientSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if (ClientSocket == INVALID_SOCKET){cout << "create Socket Error::" << endl;return -1;}sockaddr_in ClientAddr;ClientAddr.sin_family = AF_INET;ClientAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);ClientAddr.sin_port = htons(PORT);memset(ClientAddr.sin_zero,0x00,8);Ret = connect(ClientSocket, (struct sockaddr *)&ClientAddr, sizeof(ClientAddr));//==SOCKET_ERRORif (Ret == SOCKET_ERROR){cout << "connect Error::" << GetLastError() << endl;return -1;}cout << "Connect Success!"<<endl;//send while (true){cin.getline(SendBuffer,sizeof(SendBuffer));Ret = send(ClientSocket,SendBuffer,(int)sizeof(SendBuffer),0);if (Ret == SOCKET_ERROR){cout << "send Error::" <<GetLastError()<< endl;break;}memset(RecvBuffer, 0x00, sizeof(RecvBuffer));Ret = recv(ClientSocket, RecvBuffer, MAX_PATH, 0);cout << "message::" << SendBuffer << endl;cout << "receive message::" << RecvBuffer << endl;}closesocket(ClientSocket);WSACleanup();return 0;}
阅读全文
0 0
- 流式套接字实现简单的客户端/服务端通信过程
- 【网络编程】使用流式套接字实现简单的客户端/服务端通信过程
- 使用流式套接字实现简单的客户端/服务端通信过程
- 流式套接字实现简单的客户端/服务端通信过程
- 【C++】Winsock套接字编程,简单的TCP/IP通信代码(客户端、服务端)
- 套接字之客户端和服务端的一次通信
- 简单的客户端,服务端通信
- 使用简单的ServiceSockt实现服务端与客户端的通信
- Java简单实现UDP服务端和客户端的通信
- Socket TCP 协议实现服务端和客户端的简单通信
- nodejs socket实现的服务端和客户端简单通信
- Java 利用套接字Socket实现简单的服务器与客户端通信
- Socket套接字:客户端与服务端进行通信
- 简单的Socket通信客户端和服务端
- 客户端和服务端通信的简单小案列
- 简单的服务端与客户端通信代码
- Netty实现客户端和服务端的通信
- 使用UDP套接字实现简单的通信
- i386和X86各是什么意思
- 归并算法的JS实现及分析(分治,递归,归并)
- 模拟
- Java动态代理
- 奇点到来,超越人类 《Nature论文:人工智能从0-1自学打败阿法狗 》论文翻译
- 流式套接字实现简单的客户端/服务端通信过程
- 胡小胖:哪六大人群适合做微商呢?全面剖析微商职业类型!
- webView自适应实际内容高度的问题
- 3、单例模式(序列化与反序列化)
- 新手学Django大坑之加载静态图片
- 【Openjudge】英语数字转换器
- java Exception: NoClassDefFoundError: org/apache/commons/pool/KeyedObjectPoolFactory
- List add元素返回java.lang.NullPointerException
- PAT 甲级 1119. Pre- and Post-order Traversals (30)