Tcp/ip Linux编程初步

Server端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include<sys/types.h>  
#include<sys/socket.h>
#include<netdb.h>
#include<netinet/in.h>
int main()
{
int ssock;//主套接字
char *s = "X";
char *r;
int port = 3490;//本机要邦定的端口,通过此端口
struct sockaddr_in sin;//本机地址
struct sockaddr_in pin;//客户端(远端)地址
int address_size;
int tempssock;//实际与客户端交互套接字
int size = 100;

sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(port);
bind(ssock,(struct sockaddr *)&sin,sizeof(sin));
listen(ssock,5);
ssock = socket(PF_INET,SOCK_STREAM,0);
while(1)
{
address_size = sizeof(pin);
tempssock = accept(ssock,(struct sockaddr*)&pin,&address_size);
while(recv(tempssock,r,size,0) > 0)
send(tempssock,s,strlen(s),0);

close(tempssock);
break;
}
close(ssock);
return 0;
}

#include<sys/types.h>这个头文件中包含了struct sockaddr_in
#include<sys/socket.h>包含了socket的一些基础的api函数。

sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(port);
这三句合起来是地址族是AF_INET,ip地址是本机的地址。使用INADDR_ANY的好处是如果本机有多个ip地址,它都能成功的访问。而不需要指定ip。然后
是要邦定的端口。htons()是把本机的short型转换成网络的short型。

bind(ssock,(struct sockaddr *)&sin,sizeof(sin));邦定端口,需要套接字,本机地址,地址的大小

listen(ssock,5);置为被动套接字,侦听端口。

tempssock = accept(ssock,(struct sockaddr*)&pin,&address_size);//accept需要3个参数,
第一个是主套接字,第二个是客户端地址,和客户端地址大小。当服务器端接到用户的连接请求是,将连接请求中的地址信息填充到pin里。并且返回一个与客户端交互的套接
字。所以本机的地址要写明,而远端的地址自动填充就可以了。

recv(tempssock,r,size,0)接受数据,第一为与客户端连接套接字,第二个为接受的char数组(或者认为是字符串),第3个是那个字符串的大小
或长度。第四个是由需要带外控制,一般置为0。这个函数如果有数据接受到会返回接受的字符串长度,如果客户端shutdown或close了(后面还会介绍shutd
own函数),就会返回0,出错及其它会返回-1。

send(tempssock,s,strlen(s),0);和recv几乎一样,s为发送的字符串。

close(tempssock);关闭与客户端连接的套接字,这里意味这交互已经结束。这里的关闭为引用计数。如果多个进程同时引用了这一个socket,那么每次
就减一。直到最后一次才真正的关闭。

这里再介绍一个shutdown()函数,第一个参数为套接字,第二个为命令码。第二个参数为0,不允许输入,1不允许输出,2双方关闭。
我们做的Socket编程一般是unix的经典文件读写方式(open,read,write,close)。

创建服务器(循环面向连接)

1。创建套接字并邦定熟知端口,

2。套接字置为被动,侦听端口

3。循环接受来自下一个客户端的连接请求。并 创建新的套接字

4。处理客户端的请求

5关闭连接,跳转到第3步。

socket在上面看来是个int型,但是实质上socket是一个结构体包含远端地址信息,本机地址信息。而我们使用的只是socket结构体数组的一个下标.