socket实现简单通信

  1. 初始化socket
    socket库中包含很多版本的socket,需要程序员指明,具体使用哪个版本
    将我们要使用的socket版本,及其基本信息,将信息存入结构体swaData
 WSADATA wsaData;						//一个结构体用于存放socket信息
 WSAStartup(MAKEWORD(2, 2), &wsaData);	//初始化socket信息(说明所使用的版本),并将信息放入结构体
  1. 初始化socket文件,初始化成功将返回文件描述符
    SOCKET s用于存放文件描述符
    参数1:说明socket要用什么协议族
    如ipv6?v4?本地通信?还是链路通信?
    参数2:说明要使用的接口类型
    以报文传输?分组传输?还是字节流传输?或者是原始的套接字?
    参数3:具体协议
    tcp,udp,icmp,pop等
// int socket(int domain, int type, int protocol);函数原型
 SOCKET  s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  1. 初始化地址及端口号,告诉计算机目标IP,以及相应的端口号
	 sockaddr_in sockaddr;           
	 //一个结构体,有四个部分,zero不使用,剩下以下三个部分
    
    sockaddr.sin_family = PF_INET; 
    //要使用的协议,这里我们使用的是TCP/IP协议
    
    sockaddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.12"); 
    //将ip地址的字符串转为 ip,十进制的,并且判断所给的IP是否合法
   
    sockaddr.sin_port = htons(3333);
    //将端口号和IP加在一起,且进行转置(二进制倒叙,可以使用print观察下)

**

注意:接下来将区分客户机和服务机! 客户机为发起连接方,服务机为被连接

**
4. 将上述初始化完成的信息都绑定(服务机要做次操作)
s: 文件描述符
socketaddr:地址及端口信息的结构体

//将文件描述符   与   socketaddr地址绑定
  bind(s, (const struct sockaddr*)&sockaddr, sizeof(sockaddr));
  1. 服务机
    client=accept(s,&ClientAddr,&nsize)
    client: 用于接收返回的socket文件描述符

s: 服务机的socket文件描述符
clientaddr:保存客户机的IP及端口信息

因为连通了,还要继续发送消息,而不是再连,再发,只需要连一次即可

	listen(s, 2);				
	//改为监听模式,等着其他计算机来连接IP+端口

	SOCKET  client;				//初始化一个文件描述符结构体
    int nsize = sizeof(SOCKADDR);//获取socket地址信息的大小
    SOCKADDR    clientAddr;		//创建结构体用于存放用户地址及端口信息
    printf("等待对方上线中.....\n");
    client = accept(s, &clientAddr, &nsize);
    //等待客户端连接,并且接收第一个请求的连接

客户机
s:目标要连接的服务机文件描述符
sockaddr:要连接目标的IP和端口信息

connect(s, (SOCKADDR*)&sockaddr, sizeof(SOCKADDR));	//连接目标服务机
  1. 发送消息和接收消息
//接收消息
//s:目标机文件描述符
//buffer:存放消息的数组
//参数3:字符串长度
//参数4:通常为0
	recv(s, buffer, 200, NULL);
	
//发送消息
//s:目标机文件描述符
//p:存放消息的数组
//len:字符串长度
//参数4:通常为0
	send(s,p, len, NULL);
  1. 关闭通信
    closesocket(s);			
    //关闭所使用的socket文件,程序中用到的都需要关闭
    
    WSACleanup();
    //将文件描述符和地址信息解绑
  1. 完整代码
    服务机
#include <winsock2.h>
#include<Windows.h>
#include <stdio.h>
#include<iostream>
#include<string>
using namespace std;
#pragma comment (lib,"ws2_32")
#pragma warning (disable:4996)

//发送
void transmit(SOCKET client, string a)
{
    int len = a.length();
    char p[100];
    a.copy(p, len, 0);
    *(p + len) = '\0';
    send(client,p, len, NULL);
}


int main()
{
    //用来存放socket数据的结构体
    WSADATA wsaData;                      

    //OS根据请求的Socket版本,来搜索相应的Socket库
    //然后绑定找到的Socket库到该应用程序中。然后应用程序就可以使用相应的-----库-----中函数
    //MAKEWORD(2, 2),说明所使用socket版本为2.2
    WSAStartup(MAKEWORD(2, 2), &wsaData);


    //返回值为-1,表示初始化失败。
    //成功则返回对应socket版本的文件描述符号
    //(在计算机中,一切皆文件,socket也是一个文件)
    SOCKET  s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

    //一个结构体,有四个部分,zero不使用,剩下以下三个部分
    sockaddr_in sockaddr;           
    
    sockaddr.sin_family = PF_INET;                                   
    //要使用的协议,这里我们使用的是TCP/IP协议
        //注意这里的ip和端口要改成你自己的
    sockaddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.12");       
    //将ip地址的字符串转为 ip,十进制的,并且判断所给的IP是否合法?                     
    sockaddr.sin_port = htons(3333);                                 
    //同上,转置



    //将文件描述符   与   socketaddr地址绑定
    bind(s, (const struct sockaddr*)&sockaddr, sizeof(sockaddr));


    //开始监听(2表示最多可连接的客户机数量)
    //改为监听模式,而非主动发出connect连接请求
    listen(s, 2);

    SOCKET  client;
    int nsize = sizeof(SOCKADDR);
    SOCKADDR    clientAddr;
    printf("等待对方上线中.....\n");
    client = accept(s, &clientAddr, &nsize);//等待客户端连接,并且接收第一个请求的连接
    cout << "接通成功,开始会话!" << endl;
    
   
        //输入并发送
        string str;
        cin >> str;
        transmit(client, str);

        //接收输出
        char buffer[100] = {};
        recv(s, buffer, 200, NULL);
        printf("客户端一号:\n%s", *buffer);


    //关闭
    closesocket(client);
    closesocket(s);
    WSACleanup();
    return 0;
}

客户端

#include <winsock2.h>
#include <stdio.h>
#include<iostream>
#include<string>
using namespace std;
#pragma comment (lib,"ws2_32")
#pragma warning (disable:4996)
//发送
void transmit(SOCKET client, string a)          //
{
    int len = a.length();
    char p[100];
    a.copy(p, len, 0);
    *(p + len) = '\0';
    send(client, p, len, NULL);                 //
}
int     main()
{

    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);//初始化

    SOCKET  s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

    sockaddr_in sockaddr;
    sockaddr.sin_family = PF_INET;

    //注意这里的ip和端口要改成你自己的
    sockaddr.sin_addr.S_un.S_addr = inet_addr("10.20.18.214");
    sockaddr.sin_port = htons(3333);//设置要连接的IP和端口


    connect(s, (SOCKADDR*)&sockaddr, sizeof(SOCKADDR));//连接服务机
    char buffer[100] = { 0 };

        //接收输出消息
        recv(s, buffer, 200, NULL);
        printf("服务端:\n%s",buffer);

        //输入发送消息,但这里来不及,
        //cin >> str;
        //transmit(s, str);



    WSACleanup();
    printf("会话结束\n");
    system("pause");
    return 0;
}
``

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值