【1】connet
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能:用于连接服务器;
参数:
sockfd:socket函数的返回值
addr:
填充的结构体是服务器端的;
addrlen:
结a构体的大小
返回值s
-1 失败
正确 0
【2】send
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
功能:发送数据
参数:
sockfd
buf
len
flags 如果天0,相当于write();
【3】 任务
1.
实现客户端给服务器发送数据,比如发送nihao,希望服务器给客户端
回复一个“nihao***!***”;客户端接收服务器“nihao***!***”消息并打印;
nihao***!***
strcat(); //字符串拼接
***!***nihao
sprintf(temp,"***!***%s",buf);
参考 day2/1_tcp 代码
2.
如果连接到服务器的一个客户端关闭了,服务器端可以继续运行,
并且如有再有客户端想连接服务器的话,服务器同样可以接受处理;
参考 day2/1_tcp 代码
3. 使用多进程方式来实现双工通信
服务器端在接收客户端发来数据的同时,也可以给客户端发送数据;
fork()
参考 day2/2_tcp 代码
【4】优化
1. recv的返回值
2.
argv[1] = IP
atoi(argv[2]) = port
3. 对于服务器代码来说,在填充结构体里面IP的时候,
htonl(INADDR_ANY) //只能用于服务器端
你可以绑定任意主机IP
【5】如果想济南想连接北京局域网IP 192.168.1.88;
1. 花生壳工具 ()
2. 设置路由器,做端口映射;
3. 服务器
git
克隆(下载)代码:
git clone
https://github.com/ck-gao/UDP-Chat.git
【5】UDP
无连接,不可靠的传输协议;
UDP编程流程:
服务器端:
1. socket(),返回一个文件描述符,用于通信
2. bind(); //得先完成结构体的填充sockaddr_in
3. recvfrom(), //接收数据
4. sendto(), //发送数据
5. close(sockfd);
客户端:
1. socket(), 返回一个文件描述符,用于通信
2. 填充结构体,(目的是告诉程序,数据要发送给谁)
3. sendto()
4. recvfrom()
5. close();
send recv sendto recvfrom
【6】
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
第5/6参数,明确接收哪个客户端发来的数据;
【7】
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
第5/6参数,明确数据要发送给谁;
【8】项目
1. 基于UDP的在线聊天室;
2. ftp文件服务器(TCP来写的)
***************list**************
***********put filename**********
***********get filename**********
**************quit***************
list
put 1.c
get server.c
quit
伪代码
服务器端:
1. socket();
2. bind();
3. listen();
4. accepte();
5.
while(1)
{
recv();
switch( )
{
case L:
server_list(acceptfd);
case P:
server_put(acceptfd,文件名);
case G:
server_get();
}
}
服务器端功能函数实现:
server_list(int acceptfd)
{
opendir
readdir
. .. 屏蔽掉;
send(acceptfd);
}
server_put(acceptfd,文件名)
{
fd = open(文件)
recv();//读客户端发来的文件内容
write(fd);
判断一下是否写完;
}
客户端:
1. socket();
2. 填充结构体;
3. connect();
4.
while(1)
{
***************list**************
***********put filename**********
***********get filename**********
**************quit***************
input >>
fgets(buf,sizeof(buf),stdin);
吃\n;
switch(匹配第一个字符)
{
case: l
client_list(sockfd);
case: p
client_put(sockfd,文件名);
case: g
case: q
default:
input error;
}
}
客户端功能函数实现:
client_list(int sockfd)
{
字符串拼接
buf(L)
//告诉服务器客户的操作
send(sockfd,buf,sizeof(buf),0);
recv();//结构服务器发来的文件名
printf(); //打印
}
client_put(int sockfd,char *文件名)
{
buf(P 文件名)
send(sockfd,buf,sizeof(buf),0);
open(文件名)
read
write(buf);
send();
//发送一个文件读完的表示,告诉服务器;
}
client_get(int sockfd,char *文件名)
{
buf(G 文件名)
send(sockfd,buf,sizeof(buf),0);
}