一 socket 编程
先运行服务器, 本文采用线程来运行服务器, 再运行客户端
二基本概念
ip: 可唯一标识网络上的一个主机;
协议 + 端口: 可唯一标识主机中一个进程;
所以通过 IP + 协议 + 端口三元组来标识主机中的进程
三编程实现
- #pragma once
- #define WIN32
- #include<iostream>
- #include<stdio.h>
- #include "stdafx.h"
- #include<sys/types.h>
- #include<WS2tcpip.h>
- #pragma comment(lib, "ws2_32.lib")
- using namespace std;
- //typedef int(*DLLFunc)(int,int);//int 是该方法形参的类型, 有几个参数就定义几个
- //typedef int(*DLLFunc2)();
- DWORD WINAPI ThreadFunc(HANDLE Thread)
- {
- //HINSTANCE hInstLibrary = LoadLibrary(_T("E:\\V3.0\\ 新建文件夹 \\MyDll.dll"));// 要写清楚路径, 注意双斜杠
- //if (GetLastError() != 0)
- //{
- // std::cout << GetLastError();// 打印失败信息
- //}
- //if (hInstLibrary == NULL)
- //{
- // FreeLibrary(hInstLibrary);
- // return 0;
- //}
- //DLLFunc2 dllFunc3;
- //dllFunc3 = (DLLFunc2)GetProcAddress(hInstLibrary, "SocketSevert");
- //int i3 = dllFunc3();
- //cout << i3 << endl;
- //FreeLibrary(hInstLibrary);
- // 服务器端 0 成功; 22 套接字; 3 绑定; 4 监听
- WORD sockVersion = MAKEWORD(2, 2);
- WSADATA wsaData;
- if (WSAStartup(sockVersion, &wsaData) != 0)
- {
- printf("-3");
- //return -3;
- }
- // 创建通信端点: 套接字
- int sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (sockfd < 0)
- {
- printf("服务器创建套接字失败!\n");
- }
- else
- {
- printf("服务器创建套接字成功!\n");
- }
- struct sockaddr_in my_addr;
- my_addr.sin_family = AF_INET;
- my_addr.sin_port = htons(8888);
- my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- // 绑定
- int err_log = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr));
- if (err_log != 0)
- {
- printf("服务器绑定失败!\n");
- }
- else
- {
- printf("服务器绑定成功!\n");
- }
- // 监听
- err_log = listen(sockfd, 10);
- if (err_log != 0)
- {
- printf("服务器监听失败!\n");
- }
- else
- {
- printf("服务器监听成功!\n");
- }
- Sleep(10);
- int i = 0;
- while (1)
- {
- i++;
- struct sockaddr_in client_addr;
- char cli_ip[INET_ADDRSTRLEN] = "";
- socklen_t cliaddr_len = sizeof(client_addr);
- // 成功返回一个新的 socket 文件描述符, 用于和客户端通信, 失败返回 - 1
- // 表示三方握手完成, 下一步服务器调用 accept() 接受连接
- int connfd = accept(sockfd, (struct sockaddr*)&client_addr, &cliaddr_len);
- if (connfd < 0)
- {
- printf("accept 第 %d 次失败 \ n",i);
- continue;
- }
- else
- {
- printf("accept 第 %d 次成功 \ n", i);
- }
- // 接收数据
- char recv_buf[512] = { 0 };
- while (recv(connfd, recv_buf, sizeof(recv_buf), 0) > 0)
- {
- i = sizeof(recv_buf);
- while (i--)
- printf("接收数据:\n%c\n",recv_buf[i]);
- }
- }
- return 0;
- }
- int main()
- {
- //DLLFunc2 dllFunc2;
- //// hdll=LoadLibraryEx("*.dll", NULL, LOAD_WITH_ALTERED_SEARCH_PATH), 若 dll 库中有其他 dll 的调用, 就使用此语句
- //HINSTANCE hInstLibrary = LoadLibrary(_T("E:\\V3.0\\ 新建文件夹 \\MyDll.dll"));// 要写清楚路径, 注意双斜杠
- //if (GetLastError() != 0)
- //{
- // std::cout << GetLastError();// 打印失败信息
- //}
- //if (hInstLibrary == NULL)
- //{
- // FreeLibrary(hInstLibrary);
- // return 0;
- //}
- // 线程 --- 服务器
- HANDLE Thread;
- DWORD dwThreadId;
- Thread = ::CreateThread(NULL, 0, ThreadFunc, NULL, 0, &dwThreadId);
- //cout << "The new thread ID is :" << dwThreadId << endl;
- // 客户端
- WORD sockVersion = MAKEWORD(2, 2);
- WSADATA wsaData;
- if (WSAStartup(sockVersion, &wsaData) != 0)
- {
- return -1;
- }
- SOCKET sockClient = NULL;
- SOCKADDR_IN addrSrv;
- //addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
- inet_pton(AF_INET, "128.0.0.1", (void*)&addrSrv.sin_addr.S_un.S_addr);
- addrSrv.sin_family = AF_INET;
- addrSrv.sin_port = htons(8888);
- // 创建套接字
- sockClient = socket(AF_INET, SOCK_STREAM, 0);
- if (sockClient < 0)
- {
- printf("创建套接字失败!\n");
- }
- else
- {
- printf("创建套接字成功!\n");
- }
- // 网络连接
- if (connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)) == SOCKET_ERROR)
- {
- printf("connect 失败!\n");
- }
- else
- {
- printf("网络连接成功!\n");
- char send_buf[12] = { 'c','d' };
- int nRecv = ::send(sockClient, send_buf, sizeof(send_buf), 0);
- if (nRecv < 0)
- {
- printf("发送失败!\n");
- }
- else
- {
- printf("发送成功!\n");
- }
- }
- //SocketConnect 是 DLL 库里定义的方法
- //dllFunc2 = (DLLFunc2)GetProcAddress(hInstLibrary, "SocketConnect");
- //if (dllFunc2 == NULL)
- //{
- // FreeLibrary(hInstLibrary);
- // return 0;
- //}
- //int i2 = dllFunc2();
- //cout << i2 << endl;
- //FreeLibrary(hInstLibrary);
- ::WaitForSingleObject(Thread, INFINITE);
- ::CloseHandle(Thread);
- return 0;
- }
来源: http://www.bubuko.com/infodetail-2492231.html