欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Socket

程序员文章站 2022-07-11 08:27:45
...

什么是Socket

  • 它是使用Unix文件描述符(fd)和其他程序通讯的方式。用于描述IP和端口

Internet套接字的两种类型

  • 流格式(Stream Socket)SOCK_STREAM 。TCP可靠
  • 数据包格式(datagram Socket) SOCK_DGRAM。UDP不可靠

客户端与服务器的交互

Socket

C#服务器代码

  • using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;
    
    
    namespace SimpleServer
    {
        class Program
        {
            static void Main(string[] args)
            {
                // 服务器IP地址
                string ip = "127.0.0.1";
                //服务器端口
                int port = 8000;
                try
                {
                    //获得终端地址
                    IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(ip), port);
                    //创建socket
                    Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    //将socket绑定到终端地址上
                    listener.Bind(ipe);
                    //开始监听,最大允许处理1000个连接
                    listener.Listen(1000);
                    Console.WriteLine("开始监听");
                    // 开始接受客户端请求,程序在这里会阻塞住
                    Socket mySocket = listener.Accept();
                    byte[] bs = new byte[1024];
                    int n = mySocket.Receive(bs);
                    // 将客户端发来的数据返回给客户端。
                    mySocket.Send(bs);
                    mySocket.Close();
                }
                catch(Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }
        }
    }
    

C#客户端代码

  • using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace SimpleClient
    {
        class Program
        {
            static void Main(string[] args)
            {
                // 服务器IP地址
                string ip = "127.0.0.1";
                //服务器端口
                int port = 8000;
                try
                {
                    //  获得终端地址
                    IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(ip), port);
                    //创建socket
                    Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    //开始连接服务器,程序会在这里阻塞
                    client.Connect(ipe);
                    Console.WriteLine("连接到服务器");
                    string data = "hello world";
                    byte[] bs = UTF8Encoding.UTF8.GetBytes(data);
                    client.Send(bs);
                    //接受服务器传回的数据
                    byte[] rev = new byte[256];
                    client.Receive(rev);
                    Console.WriteLine(UTF8Encoding.UTF8.GetString(rev));
                    client.Close();
                   
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }
        }
    }
    

sockaddr和sockaddr_in的区别

  • 都是用来处理网络通信的地址
  • sockaddr把ip地址和端口混在一起。#include <sys/socket.h>定义
  • sockaddr_in把ip和端口分开。 在 #include<netinet/in.h>或#include <arpa/inet.h>中定义 
  • 套接字  = IP + 端口
  • Socket

htons()[host to net short]

  • htons()端口号由主机字节序转换为网络字节序的整数
  • 主机字节序 = 小端字节序(现代PC多是小端)       网络字节序  =  大端字节序 。  并学会如何测试大小端

inet_addr()

  • inet_addr()将IP字符串转化为网络字节序的整数值

inet_ntoa()[network to ascill]

  • inet_ntoa()将in_addr结构体输出成IP字符串 print(mysocket.sin_addr);

struct timeval

#include "sys/time.h"
 
struct timeval  
{  
    __time_t tv_sec;        /* Seconds. */  
    __suseconds_t tv_usec;  /* Microseconds. */  
}; 

Select

  • int select(int n,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout);
  • select(A,B,C,D,E) A需要检查的文件描述字个数+1,B检查可读性的一组文件描述符,C检查可写性的一组文件描述符,D异常文件描述符,E多久返回超时