【学习笔记】【计算机网络】网络通信实例;本地进程通过域套接字、回环地址;

一、本机通信分类

1、AF_INET 与 AF_UNIX

int socket(int domain, int type, int protocol);

  • 其中 domain
  • AF_UNIX(本机通信)
  • AF_INET(TCP/IP – IPv4)
  • AF_INET6(TCP/IP – IPv6)
  • 其中 “type”参数指的是套接字类型,常用的类型有:
  • SOCK_STREAM(TCP流)
  • SOCK_DGRAM(UDP数据报)
  • SOCK_RAW(原始套接字)

2、区别

  • 两者路径不同;一个通过本地IPC 通信;一个通过完整网络通信;
  • bind()的地址结构分别为sockaddr_in(制定IP端口)和sockaddr_un(指定路径名)
  • AF_INET需经过多个协议层的编解码,消耗系统cpu,并且数据传输需要经过网卡,受到网卡带宽的限制。
    AF_UNIX数据到达内核缓冲区后,由内核根据指定路径名找到接收方socket对应的内核缓冲区,直接将数据拷贝过去,不经过协议层编解码,节省系统cpu,并且不经过网卡,因此不受网卡带宽的限制;
  • AF_UNIX的传输速率远远大于AF_INET;
  • AF_INET不仅可以用作本机的跨进程通信,同样的可以用于不同机器之间的通信,其就是为了在不同机器之间进行网络互联传递数据而生。而AF_UNIX则只能用于本机内进程之间的通信。

在这里插入图片描述

在这里插入图片描述

二、linux实例

1、unix 域套接字的本地socket 文件通信;

  • 服务端;
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdlib.h>
 
int main (int argc,char *argv[])
{
        int server_sockfd, client_sockfd;
        int server_len, client_len;
        struct sockaddr_un server_address;     /*声明一个UNIX域套接字结构*/
        struct sockaddr_un client_address;
        int i, bytes;
        char ch_send, ch_recv;
 
        unlink ("server_socket");      /*删除原有server_socket对象*/
 
        /*创建 socket, 通信协议为AF_UNIX, SCK_STREAM 数据方式*/
        server_sockfd = socket (AF_UNIX, SOCK_STREAM, 0);
 
        /*配置服务器信息(通信协议)*/
        server_address.sun_family = AF_UNIX;
 
        /*配置服务器信息(socket 对象)*/
        strcpy (server_address.sun_path,"server_socket");
 
        /*配置服务器信息(服务器地址长度)*/
        server_len =sizeof (server_address);
 
        /*绑定 socket 对象*/
        bind (server_sockfd, (struct sockaddr *)&server_address, server_len);
 
        /*监听网络,队列数为5*/
        listen (server_sockfd, 5);
 
        printf ("Server is waiting for client connect...\n");
 
        client_len =sizeof (client_address);
 
        /*接受客户端请求; 第2个参数用来存储客户端地址; 第3个参数用来存储客户端地址的大小*/
        /*建立(返回)一个到客户端的文件描述符,用以对客户端的读写操作*/
        client_sockfd = accept (server_sockfd, (struct sockaddr *)&server_address, (socklen_t *)&client_len);
        if (client_sockfd == -1) {
                perror ("accept");
                exit (EXIT_FAILURE);
        }
 
        printf ("The server is waiting for client data...\n");
 
        for (i = 0, ch_send ='1'; i < 5; i++, ch_send++) {
                if ((bytes = read (client_sockfd, &ch_recv, 1)) == -1) {
                        perror ("read");
                        exit (EXIT_FAILURE);
                }
 
                printf ("The character receiver from client is %c\n", ch_recv);
 
                sleep (1);
 
                if ((bytes = write (client_sockfd, &ch_send, 1)) == -1) {
                        perror ("read");
                        exit (EXIT_FAILURE);
                }
        }
 
                close (client_sockfd);
                unlink ("server socket");
}
  • 客户端
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdlib.h>
 
int main (int argc,char *argv[])
{
    struct sockaddr_un address;
    int sockfd;
    int len;
    int i, bytes;
    int result;
    char ch_recv, ch_send;
 
    /*创建socket,AF_UNIX通信协议,SOCK_STREAM数据方式*/
    if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
            perror ("socket");
            exit (EXIT_FAILURE);
    }
 
    address.sun_family = AF_UNIX;
    strcpy (address.sun_path,"server_socket");
    len =sizeof (address);
 
    /*向服务器发送连接请求*/
    result = connect (sockfd, (struct sockaddr *)&address, len);
    if (result == -1) {
        printf ("ensure the server is up\n");
        perror ("connect");
        exit (EXIT_FAILURE);
    }
 
    for (i = 0, ch_send ='A'; i < 5; i++, ch_send++) {
        if ((bytes = write(sockfd, &ch_send, 1)) == -1) {/*发消息给服务器*/
            perror ("write");
            exit (EXIT_FAILURE);
        }
 
        sleep (2);   /*休息二秒钟再发一次*/
 
        if ((bytes = read (sockfd, &ch_recv, 1)) == -1) {/*接收消息*/
            perror ("read");
            exit (EXIT_FAILURE);
        }
 
        printf ("receive from server data is %c\n", ch_recv);
    }
    close (sockfd);
 
    return (0);
}

2、socket 四元组通信;

  • 服务端

#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
#pragma comment(lib,"Ws2_32.lib")
#include <memory.h>
 
#define BUF_SIZE 4096
#define QUEUE_SIZE 5
 
DWORD WINAPI ThreadProcServerConmunicate(
	_In_ LPVOID lpParameter
) {
	SOCKET * psc = (SOCKET *)lpParameter;
 
	int receByt = 0;
	while (1)
	{
		char buf[BUF_SIZE];
		receByt = recv(*psc, buf, BUF_SIZE, 0);
		buf[receByt] = '\0';
		if (receByt>0)
		{
			printf("%u : 接收的消息是:%s\n", *psc, buf);
		}
		else
		{
			printf("接收消息结束!");
			break;
		}
 
	}
	int ic = closesocket(*psc);
	free(psc);
	return 0;
}
 
 
int main() {
	
	WSADATA wsd;
	WSAStartup(MAKEWORD(2, 0), &wsd);
 
	SOCKET s = NULL;
	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	struct sockaddr_in ch;
	memset(&ch, 0, sizeof(ch));
	ch.sin_family = AF_INET;
	ch.sin_addr.s_addr = INADDR_ANY;
	ch.sin_port = htons(5174);
	int b = bind(s, (struct sockaddr *) &ch, sizeof(ch));
	
	int l = listen(s, QUEUE_SIZE);
	printf("正在监听本机的5174端口\n");
 
	while (1) {
		SOCKET * psc = (SOCKET *)malloc(sizeof(SOCKET));
		*psc = accept(s, 0, 0);
		printf("一个客户端已经连接到本机的5174端口,SOCKET是 : %u \n", *psc);
 
		CreateThread(NULL,
			0,
			&ThreadProcServerConmunicate,
			psc,
			0,
			NULL
		);
	}
	
	int is = closesocket(s);
	WSACleanup();
	return 0;
}
  • 客户端
#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
#pragma comment(lib,"Ws2_32.lib")
#include <memory.h>
 
#define BUF_SIZE 4096
 
void main()
{
	WSADATA wsd;
	WSAStartup(MAKEWORD(2, 0), &wsd);
 
	SOCKET s = NULL;
	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	struct sockaddr_in ch;
	memset(&ch, 0, sizeof(ch));
	ch.sin_family = AF_INET;
	ch.sin_addr.s_addr = inet_addr("127.0.0.1");
	ch.sin_port = htons(5174);
 
	int c = connect(s, (struct sockaddr *) &ch, sizeof(ch));
	printf("已经连接到服务器的5174端口,现在可以向服务器发送消息了!\n");
 
	char info[1024], buf[BUF_SIZE];
 
	while (1)
	{
		gets(info);
		if (info[0] == '\0')
			break;
		strcpy(buf, info);
		int nsend = send(s, buf, strlen(buf), 0);
		Sleep(500);
	}
	int ic = closesocket(s);
	WSACleanup();
	return 0;

参考

https://blog.csdn.net/sandware/article/details/40923491

https://www.cnblogs.com/lance-ehf/p/3772808.html

https://blog.csdn.net/u011580175/article/details/80306414

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值