TCP:传输控制协议。
特点:传输层协议
有连接
面向字节流
可靠传输
UDP编程思想
server.c
- socket()服务器创建套接字
- bind()绑定端口号
- listen()监听客户端发来的请求
- accept()接受client请求
- 接收成功,为客户端提供服务service()
代码:
问题:为什么要创建孙子进程?
服务器端可以创建多个子进程去处理客户端发来的数据,当每次收到一个新的客户端的连接请求的时候,我们就会fork()出一个子进程,父进程用于等待子进程,子进程用于执行,读客户端法的数据的操作,终止子进程,儿子进程被它的父进程回收,此时的孙子进程就是一个孤儿进程,被1号进程(操作系统回收),这样做的目的就是,不要让儿子进程等待孙子进程太久而消耗太多的系统资源.
注意:父进程关闭套接字,子进程关闭监听套接字这是因为,父进程是来监听的,不需要通信子进程是读取信息的,不需要监听.
客户端编程思想
#include<stdio.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<string.h>
#define MAX 128
int main(int argc,char* argv[]){
int sock=socket(AF_INET,SOCK_STREAM,0);//创建客户端套接字
if(sock<0){
printf("sock error!\n");
return 1;
}
struct sockaddr_in server;
server.sin_family=AF_INET;
server.sin_port=htons(atoi(argv[2]));
server.sin_addr.s_addr=inet_addr(argv[1]);
if(connect(sock,(struct sockaddr*)&server,sizeof(server))<0){//请求连接
printf("connect error!\n");
return 2;
}
char buf[MAX];
while(1){//循环发送请求内容
printf("please enter# ");
fflush(stdout);
ssize_t s=read(0,buf,sizeof(buf)-1);
if(s>0){
buf[s-1]=0;
if(strcmp("quit",buf)==0){
printf("client quit!\n");
break;
}
write(sock,buf,strlen(buf));
s=read(sock,buf,sizeof(buf)-1);
buf[s]=0;
printf("Server Echo# %s\n",buf);
}
}
close(sock);
return 0;
}
需要注意的是,客户端不需要固定的端口号,所以没必要绑定端口号。