#include "nb30.h"巧老改
#include "winsock2.h"
#pragma comment(lib,"WS2_32.LIB")
#include <Windows.h>//这个肯含察定要的
#include <Winuser.h>
#include "stdafx.h"#include <WinSock2.h> //windows socket的头文件#include <Windows.h>#include <iostream>#include <thread>#include <mutex>#include <process.h>#pragma comment(lib, "ws2_32.lib") //连接winsock2.h的静态库文件using namespace stdmutex m//定义结构体用来设置typedef struct my_file{ SOCKET clientSocket //文件内部包含了一个手首SOCKET 用于和客户端进行通信 sockaddr_in clientAddr //用于保存客户端的socket地址 int id //文件块的序号}FDWORD WINAPI transmmit(const LPVOID arg){ //实际上这里为了追求并发性不应该加锁,上锁是为了方便看输出 m.lock() F *temp = (F*)arg //获取文件的序号 //int file_id = temp->id //获取客户机的端口号 //ntohs(temp -> clientAddr.sin_port) cout <<乎衫 "测试开始,等待客户端发送消息..." << endl //从客户端处接受数据 char Buffer[MAXBYTE] = { 0 } //缓冲区 recv(temp->clientSocket, Buffer, MAXBYTE, 0) //recv方法 从客户端通过clientScocket接收 cout << "线程" << temp->id << "从客户端的" << ntohs(temp->clientAddr.sin_port) << "号端口收到:" << Buffer << endl //发送简单的字符串到客户端 const char* s = "Server file" send(temp->clientSocket, s, strlen(s)*sizeof(char)+1, NULL) cout << "线程" << temp->id << "通过客户端的" << ntohs(temp->clientAddr.sin_port) << "号端口发送:" << s << endl m.unlock() return 0}int main(){ WSADATA wsaData //第一个参数是winsocket load的版本号(2.2) WSAStartup(MAKEWORD(2, 3), &wsaData) //创建服务器端的socket(协议族, sokcet类型) SOCKET servSocket = socket(AF_INET, SOCK_STREAM, 0)//如果改成SOCK_DGRAM则使用UDP sockaddr_in servAddr //服务器的socket地址,包含sin_addr表示IP地址,sin_port保持端口号和sin_zero填充字节 memset(&servAddr, 0, sizeof(SOCKADDR)) //初始化socket地址 servAddr.sin_family = PF_INET //设置使用的协议族 servAddr.sin_port = htons(2017) //设置使用的端口 servAddr.sin_addr.s_addr = inet_addr("127.0.0.1") //define s_addr = S_un.S_addr ::bind(servSocket, (SOCKADDR *)&servAddr, sizeof(SOCKADDR)) //将之前创建的servSocket和端口,IP地址绑定 HANDLE hThread[20] //获取句柄 listen(servSocket, 20) //监听服务器端口 for (int i = 0 i < 20 i++) { F *temp = new F //创建新的传输结构体 sockaddr_in clntAddr int nSize = sizeof(SOCKADDR) SOCKET clientSock = accept(servSocket, (SOCKADDR*)&clntAddr, &nSize) //temp数据成员赋值 temp->clientSocket = clientSock temp->id = i + 1 temp->clientAddr = clntAddr //通过句柄创建子线程 hThread[i] = 毕顷数CreateThread(NULL, 0, &transmmit, temp, 0, NULL) } //等待子线程完成 WaitForMultipleObjects(20, hThread, TRUE, INFINITE) cout << WSAGetLastError() << endl //查看错误信息 //关闭socket,释放winsock closesocket(servSocket) WSACleanup() cout << "服务器连接已关闭。" << endl system("pause") return 0}注意bind之后要监听(listen),并且accpet请求队列中的socket以建立连接。
大概流程就是bind -> listen -> if someone connects -> accept,如果是UDP就可以省略listen和accept(这两个分别是监听和接受新连接,然而UDP并不需要建立连接),直接收发(sendto和recvfrom)。
客户端则只需要创建一个socket,填写好地址信息,通过connect发送连接请求,之后就可以send或者recv了。如果是UDP则直接sendto和recvfrom,不需要connect(UDP无连接)。
Client代码:
#include "stdafx.h"#include <WinSock2.h> //windows socket的头文件#include <Windows.h>#include <iostream>#include <thread>#include <process.h>#pragma comment(lib, "ws2_32.lib") //连接winsock2.h的静态库文件using namespace stdint main(){ //加载winsock库 WSADATA wsadata WSAStartup(MAKEWORD(2, 3), &wsadata) //客户端socket SOCKET clientSock = socket(PF_INET, SOCK_STREAM, 0) //初始化socket信息 sockaddr_in clientAddr memset(&clientAddr, 0, sizeof(SOCKADDR)) //clientAddr.sin_addr.s_addr = htonl(INADDR_ANY) clientAddr.sin_addr.s_addr = inet_addr("127.0.0.1") clientAddr.sin_family = PF_INET clientAddr.sin_port = htons(2017) //建立连接 connect(clientSock, (SOCKADDR*)&clientAddr, sizeof(SOCKADDR)) cout << "已建立连接。" << endl char* s = new char[100] cout << "请输入你要发送的文字消息: " cin >> s send(clientSock, s, strlen(s)*sizeof(char) + 1, NULL) cout << "已发送:" << s << endl system("pause") char Buffer[MAXBYTE] = { 0 } recv(clientSock, Buffer, MAXBYTE, 0) cout << "通过端口:" << ntohs(clientAddr.sin_port) << "接收到:" << Buffer << endl closesocket(clientSock) WSACleanup() cout << "客户端连接已关闭。" << endl system("pause") return 0}
这里将TCP最大监听连接数设置成了20,最多可以同时接受20个连接请求。
这里实现的只是最基础的字符串传输,之后还要实现文件传输...Orz
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)