网络

Silk通过内置的socket系列函数可进行网络的读写操作,socket即套接字,socket 通信技术就是两台联网的计算机之间交换数据的技术。
下面列出了内置的socket操作函数:

listen函数
对于服务器端程序,使用 _fun("sock_listen", port) 函数让套接字监听在某个端口,再调用 accept 函数,就可以随时响应客户端的请求了。
第一个参数为函数名sock_listen,第二个port为端口号,成功后返回socket的句柄,失败返回null,失败的原因一般为端口被其它程序占用。

accept函数
listen函数成功后,使用 _fun("sock_accept", sock) 就可以接受客户端的请求了。
第一个参数为函数名sock_accept,第二个sock为listen函数返回的socket句柄。
accept调用后会返回一个新的socket句柄来和客户端通信,后面的收发数据要使用这个新的socket句柄。

recv函数
accept函数接受客户端的请求后,就可以调用_fun("sock_recv", sock, size)接收从客户端来的数据。
当然,客户端也可以通过recv函数接收来自服务端的数据。
第一个参数为函数名sock_recv,第二个sock为socket句柄,size为接收缓冲区的大小(字节数)。

send函数
send函数用来发送数据,调用_fun("sock_send", sock, data)可以从服务端向客户端发送数据。
当然,客户端也可以通过send函数向服务端发送数据。
第一个参数为函数名sock_send,第二个sock为socket句柄,data是需要发送的数据,为字符串类型,可以包含二进制数据。

connect函数
对于客户端程序,使用 _fun("sock_connect", host, port) 函数可以连接到服务器。
第一个参数为函数名sock_connect,第二个host为服务器的地址,一般为域名或IP地址,port为服务器的端口号。
成功后返回socket的句柄,失败返回null。连接成功后可以通过recv和send函数收发数据。

close函数
使用 _fun("sock_close", sock) 函数可以关闭socket连接,并立即释放资源。
第一个参数为函数名sock_close,第二个sock为socket句柄。

shutdown函数
使用 _fun("sock_shutdown", sock, how) 函数可以单方向或者双方向关闭socket连接。
第一个参数为函数名sock_shutdown,第二个sock为socket句柄,how为关闭模式,有如下3种选择:
  1. how = 0 ,关闭socket上的接收操作。
  2. how = 1 ,关闭socket上的发送操作。
  3. how = 2 ,关闭socket上的接收和发送操作。
remoteaddr函数
使用 _fun("sock_remoteaddr", sock) 函数可以获取连接端的IP地址和端口。
第一个参数为函数名sock_remoteaddr,第二个sock为socket句柄。
成功后返回一个数组,数组的第一个元素为IP地址,第二个为端口号。

Silk安装包里有个封装了全部文件操作的类CSocket,方便用户的操作:
class CSocket()
{
    self.sock=null;

    func listen(port)
    {
        self.sock=_fun("sock_listen",port);
        return self.sock;
    }
    func accept()
    {
        sock= _fun("sock_accept",self.sock);
        client_sock=CSocket();
        client_sock.sock=sock;
        return client_sock;
    }
    func send(data)
    {
        return _fun("sock_send",self.sock,data);
    }
    func recv(size)
    {
        return _fun("sock_recv",self.sock,size);
    }
    func remote_addr()
    {
        return _fun("sock_remoteaddr",self.sock);
    }
    func connect(host,port)
    {
        self.sock=_fun("sock_connect",host,port);
        return self.sock;
    }
    func close()
    {
        _fun("sock_close",self.sock);
     }
     func shutdown(how)
    {
        //how has 3 options (0:shutdown receive, 1:shutdown send, 2:shutdown both)
        _fun("sock_shutdown",self.sock,how);
     }  
     func timeout(seconds)
    {
        _fun("sock_timeout",self.sock,seconds);
     }   
}


使用CSocket类的例子:
// A simple echo http server

#include "include\socket.si"

func process_client(client)
{
    //get data from client(browser)
    data=client.recv(4096);
    //send data to client
    client.send("HTTP/1.0 200 OK\r\n\r\nHello, this is a simple http server.");
    //close socket
    client.close();
    
    print("sent response to browser");
}

main()
{
    port=80;
    printf("http server is starting to run on port %d\n",port);
    server_sock=CSocket();
    if(!server_sock.listen(port))//listen on a port
    {
        printf("error running on port %d\n",port);
        return;
    }
        
    while(true)
    {
        client_sock= server_sock.accept(); //accept the client request
        _createthread(process_client,client_sock); //process the client request in thread
        
    }
    server_sock.close();
}