THINKING IN SOCKET PROGRAMMING

(2009.10.1 整理自 《Pocket Guide to TCP/IP Sockets (C Version))

ONE. socket基础

为了使用TCPUPD通信,程序首先要请求OS生成套接字实例。这里使用了socket()函数。

Int socket(int PROTOCOLFAMILY, int TYPE, int PROTOCOL)

常数 PF_INET表示互联网协议家族,我们在这里只用到它。

返回任意正数表示成功,-1表示失败。

关闭 int close(int socket) 成功返回0, 失败返回-1


socket API 为了关联套接字和地址信息定义了构造体-sockaddr:

struct sockaddr

{

unsigned short sa_family; /* address family (e.g. AF_INET) */

char sa_data[14]; /* family-specific address information */

};


第一个参数我们只用表示互联网地址家族的常数 AF_INET


Struct in_addr

{

unsigned long s_addr; /* Internet address(32 bits) */

};

struct sockaddr_in

{

unsigned short sin_family /* Internet protocol (AF_INET) */

unsigned short sin_port; /* address port (16 bits) */

struct in_addr sin_addr; /* Internet address(32 bits) */

char sin_zero[8]; /* Not used */

};


sockaddr_in 是为了使sockaddr结构体数据部分符合互联网协议而修正的。

所以填充了sockaddr_in字段之后,将它castsockaddr


我们先重点研究下TCP的发送接收,因为TCP套接字通信和文件的IO很相似。


TCP客户端的4个过程:

  1. 利用socket() 生成 TCP套接字;

  2. 利用connect()定义与服务器的连接;

  3. 利用send() recv()进行通信;

  4. 利用close()断开连接;


int connect(int socket, struct sockaddr * foreignAddress, unsigned int addressLength)

这里的 socket 是由socket()生成的识别号。

ForeignAddresssocketaddr_in类型的指向服务器IP地址和端口号的指针。

AddressLength 固定为sizeof(struct sockaddr_in)


int send(int socket, const void * msg, unsigned int msgLength, int flags)

int recv(int socket, void * rcvBuffer, unsigned int bufferLength, int flags)


send()的默认行为是发送所有数据后block.

recv()默认行为是至少要等一定比特移动之后在BLOCK

send()recv()flags参数可以改变默认行为,为0时是默认行为。

send()recv()返回发送或接收的字节数或者返回失败信息-1


下面的程序展示了客户端与叫做“echo”的服务器通信过程,有很多系统为了调试或测试使用这种服务器,这种服务器这是简单地将接收到的信息重新发回客户端。


 (待续)

你可能感兴趣的:(programming)