tcp点播
- 制定通信规则:程序员自己制定的
客户端发给服务器的信息,服务器都能收到,但是服务器无法判断收到的信息究竟是要广播给所有人,还是要点播给某个人
比如:制定了如下规则(仅供参考)
all:hello --》表示广播
ip地址:端口号:hello --》表示点播给ip对应的客户端
通信规则总体的原则:让服务器能够清楚地知道该如何处理信息
2. 刻意练习
有目的强迫自己使用讲过的知识点
udp协议
1. 通信的流程
udp谁先发送谁就是发送端
发送端 接收端
socket(SOCK_DGRAM) socket(SOCK_DGRAM)
bind() bind()
收发信息 收发信息
close() close()
2. 相关的接口函数
(1)发送信息
ssize_t sendto(int socket, const void *message, size_t length,int flags, const struct sockaddr *dest_addr, socklen_t dest_len);
返回值:发送的字节数 失败 -1
参数:前面四个参数跟send一样
dest_addr --》对方的ip和端口号
(2)接收信息
ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags, struct sockaddr *restrict address, socklen_t *restrict address_len);
返回值(重点):
区别recv/read的返回值
recvfrom 成功返回接收的字节数
失败 -1
对方退出了,recvfrom依然阻塞,也不会返回0
参数:前面四个参数跟recv一样
address --》存储对方的ip和端口号(谁发信息给我,就存放谁的ip和端口号)
address_len --》地址长度,要求是指针
3. udp广播
发送端 接收端
socket() socket()
bind() bind()
//设置套接字的属性为可以广播 recvfrom()
setsockopt() close()
sendto()(重点:必须使用广播地址)
close()
(1)设置套接字的属性为可以广播
int on=1;
setsockopt(udpsock,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));
4. udp组播
组播:是广播的一种特殊形式,给指定组里面的所有主机发送信息
发送端 接收端
socket() socket()
bind() bind()
//设置套接字的属性为可以广播 //把接收端添加到组播组里面(重点)
setsockopt() recvfrom()
sendto()(重点:必须使用组播地址) close()
close()
(1)把接收端添加到组播组里面(重点)
struct ip_mreq mreq; //定义结构体变量存放组播地址
bzero(&mreq, sizeof(mreq));
mreq.imr_multiaddr.s_addr = inet_addr(“跟发送端使用的组播地址一致”); // D类地址
mreq.imr_interface.s_addr = htonl(INADDR_ANY); // 必须用这个宏定义
setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof(mreq));
ip地址分类
分为: A B C D四类地址
10.45.56,100 —》A类地址
TCP广播
服务器
#include "myhead.h"
//定义内核链表
struct clientlist
{
char ip[16]; //存放ip
unsigned short someport; //存放端口号
int sock; //存放套接字
struct list_head mypoint;
};
struct clientlist *myhead;
//初始化链表头
struct clientlist *init_list()
{
struct clientlist *head=malloc(sizeof(struct clientlist));
INIT_LIST_HEAD(&(head->mypoint));
return head;
}
void *routine(void *arg)
{
int ret;
char buf[100];
struct clientlist *p=(struct clientlist *)arg;
struct clientlist *pos,*n;
while(1)
{
bzero(buf,100);
ret=read(p->sock,buf,100); //接收某个客户端发送的信息
if(ret==0) //说明客户端退出
{
//删除断开的客户端
list_for_each_entry_safe(pos, n,&(myhead->mypoint),mypoint)
{
if(pos->sock==p->sock)
list_del(&(pos->mypoint));
}
break;
}
printf("客户端发送过来的信息是:%sn",buf);
//遍历链表转发出去
list_for_each_entry(pos,&(myhead->mypoint),mypoint)
{
//排除自己
if(pos->sock!=p->sock)
write(pos->sock,buf,strlen(buf));
}
}
pthread_exit(NULL);
}
int main()
{
pthread_t id;
int tcpsock;
int newsock;
int ret;
char buf[100];
//初始化表头
myhead=init_list();
//定义ipv4地址结构体变量
struct sockaddr_in bindaddr;
bzero(&bindaddr,sizeof(bindaddr));
bindaddr.sin_family=AF_INET;
bindaddr.sin_addr.s_addr=htonl(INADDR_ANY); //绑定服务器自己的ip地址
bindaddr.sin_port=htons(10086); //绑定服务器自己的端口号
struct sockaddr_in clientaddr;
bzero(&clientaddr,sizeof(clientaddr));
int addrsize=sizeof(clientaddr);
//创建tcp套接字
tcpsock=socket(AF_INET,SOCK_STREAM,0);
if(tcpsock==-1)
{
perror("创建tcp套接字!n");
return -1;
}
printf("旧的文件描述符:%dn",tcpsock);
//绑定ip和端口号
ret=bind(tcpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
if(ret==-1)
{
perror("绑定失败!n");
return -1;
}
//监听
ret=listen(tcpsock,8);
if(ret==-1)
{
perror("监听失败!n");
return -1;
}
while(1)
{
//接收客户端的连接请求
newsock=accept(tcpsock,(struct sockaddr *)&clientaddr,&addrsize);
if(newsock==-1)
{
perror("接收客户端的连接请求失败!n");
return -1;
}
printf("有新的客户端连接成功了,新的文件描述符:%dn",newsock);
printf("有新的客户端连接成功了,他的IP地址是:%sn",inet_ntoa(clientaddr.sin_addr));
printf("有新的客户端连接成功了,他的端口号是:%hun",ntohs(clientaddr.sin_port));
//把文件描述符存放到链表中
struct clientlist *newnode=malloc(sizeof(struct clientlist));
newnode->sock=newsock;
strcpy(newnode->ip,inet_ntoa(clientaddr.sin_addr));
newnode->someport=ntohs(clientaddr.sin_port);
INIT_LIST_HEAD(&(newnode->mypoint));
//插入到链表的尾部
list_add_tail(&(newnode->mypoint),&(myhead->mypoint));
//立马新建线程接收这个客户端发送的信息
pthread_create(&id,NULL,routine,newnode);
}
}
客户端
#include "myhead.h"
int tcpsock;
void *routine(void *arg)
{
char buf[100];
int ret;
while(1)
{
bzero(buf,100);
ret=read(tcpsock,buf,100);
if(ret==0) //说明服务器断开连接
{
printf("服务器挂了!n");
exit(-1); //结束整个进程
}
printf("服务器转发过来的信息是:%sn",buf);
}
}
int main()
{
pthread_t id;
int ret;
char buf[100];
//定义ipv4地址结构体变量
struct sockaddr_in bindaddr;
bzero(&bindaddr,sizeof(bindaddr));
bindaddr.sin_family=AF_INET;
bindaddr.sin_addr.s_addr=htonl(INADDR_ANY); //绑定客户端自己的ip地址
bindaddr.sin_port=htons(10000); //绑定客户端自己的端口号
//定义结构体变量存放对方(服务器)的ip和端口号
struct sockaddr_in serveraddr;
bzero(&serveraddr,sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_addr.s_addr=inet_addr("192.168.24.3"); //服务器的ip地址
serveraddr.sin_port=htons(10086); //服务器的端口号
//创建tcp套接字
tcpsock=socket(AF_INET,SOCK_STREAM,0);
if(tcpsock==-1)
{
perror("创建tcp套接字!n");
return -1;
}
//绑定ip和端口号
ret=bind(tcpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
if(ret==-1)
{
perror("绑定失败!n");
return -1;
}
//连接服务器
ret=connect(tcpsock,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
if(ret==-1)
{
perror("连接服务器!n");
return -1;
}
//创建线程专门接收服务器的信息
pthread_create(&id,NULL,routine,NULL);
//发送信息给服务器
while(1)
{
bzero(buf,100);
printf("请输入要发送给服务器的信息!n");
scanf("%s",buf);
write(tcpsock,buf,strlen(buf));
}
close(tcpsock);
return 0;
}
TCP广播和点播融合
#include "myhead.h"
pthread_attr_t myattr;
void *fun(void *arg)
{
pthread_attr_destroy(&myattr);
}
//定义内核链表
struct clientlist
{
char ip[16]; //存放ip
unsigned short someport; //存放端口号
int sock; //存放套接字
struct list_head mypoint;
};
struct clientlist *myhead;
//初始化链表头
struct clientlist *init_list()
{
struct clientlist *head=malloc(sizeof(struct clientlist));
INIT_LIST_HEAD(&(head->mypoint));
return head;
}
void *routine(void *arg)
{
int ret;
char msg[100];
char buf[100];
struct clientlist *p=(struct clientlist *)arg;
struct clientlist *pos,*n;
while(1)
{
bzero(buf,100);
bzero(msg,100);
ret=read(p->sock,buf,100); //接收某个客户端发送的信息
if(ret==0) //说明客户端退出
{
//删除断开的客户端
list_for_each_entry_safe(pos, n,&(myhead->mypoint),mypoint)
{
if(pos->sock==p->sock)
list_del(&(pos->mypoint));
}
break;
}
printf("客户端%s,端口号:%hu 发送过来的信息是:%sn",p->ip,p->someport,buf);
//切割字符串,判断究竟是群发还是点播
char *q=strtok(buf,":"); //all:hello或者20000:hello
strcpy(msg,strtok(NULL,":"));
if(strcmp(q,"all")==0) //群发
{
//遍历链表转发出去
list_for_each_entry(pos,&(myhead->mypoint),mypoint)
{
//排除自己
if(pos->sock!=p->sock)
write(pos->sock,msg,strlen(msg));
}
}
else //点播
{
//遍历链表找到要点播的对象
list_for_each_entry(pos,&(myhead->mypoint),mypoint)
{
if(pos->someport==atoi(q))
write(pos->sock,msg,strlen(msg));
}
}
}
pthread_exit(NULL);
}
int main()
{
signal(SIGINT,fun);
pthread_t id;
int tcpsock;
int newsock;
int ret;
char buf[100];
//初始化表头
myhead=init_list();
//定义线程属性变量并初始化
pthread_attr_init(&myattr);
//调用你想设置的属性对应的接口函数
pthread_attr_setdetachstate(&myattr,PTHREAD_CREATE_DETACHED);
//定义ipv4地址结构体变量
struct sockaddr_in bindaddr;
bzero(&bindaddr,sizeof(bindaddr));
bindaddr.sin_family=AF_INET;
bindaddr.sin_addr.s_addr=htonl(INADDR_ANY); //绑定服务器自己的ip地址
bindaddr.sin_port=htons(10086); //绑定服务器自己的端口号
struct sockaddr_in clientaddr;
bzero(&clientaddr,sizeof(clientaddr));
int addrsize=sizeof(clientaddr);
//创建tcp套接字
tcpsock=socket(AF_INET,SOCK_STREAM,0);
if(tcpsock==-1)
{
perror("创建tcp套接字!n");
return -1;
}
printf("旧的文件描述符:%dn",tcpsock);
//设置端口重复使用
int on=1;
setsockopt(tcpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
//绑定ip和端口号
ret=bind(tcpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
if(ret==-1)
{
perror("绑定失败!n");
return -1;
}
//监听
ret=listen(tcpsock,8);
if(ret==-1)
{
perror("监听失败!n");
return -1;
}
while(1)
{
//接收客户端的连接请求
newsock=accept(tcpsock,(struct sockaddr *)&clientaddr,&addrsize);
if(newsock==-1)
{
perror("接收客户端的连接请求失败!n");
return -1;
}
printf("有新的客户端连接成功了,新的文件描述符:%dn",newsock);
printf("有新的客户端连接成功了,他的IP地址是:%sn",inet_ntoa(clientaddr.sin_addr));
printf("有新的客户端连接成功了,他的端口号是:%hun",ntohs(clientaddr.sin_port));
//把文件描述符存放到链表中
struct clientlist *newnode=malloc(sizeof(struct clientlist));
newnode->sock=newsock;
strcpy(newnode->ip,inet_ntoa(clientaddr.sin_addr));
newnode->someport=ntohs(clientaddr.sin_port);
INIT_LIST_HEAD(&(newnode->mypoint));
//插入到链表的尾部
list_add_tail(&(newnode->mypoint),&(myhead->mypoint));
//立马新建线程接收这个客户端发送的信息
pthread_create(&id,&myattr,routine,newnode);
}
}
客户端
#include "myhead.h"
int tcpsock;
void *routine(void *arg)
{
char buf[100];
int ret;
while(1)
{
bzero(buf,100);
ret=read(tcpsock,buf,100);
if(ret==0) //说明服务器断开连接
{
printf("服务器挂了!n");
exit(-1); //结束整个进程
}
printf("服务器转发过来的信息是:%sn",buf);
}
}
int main()
{
pthread_t id;
int ret;
char buf[100];
//定义ipv4地址结构体变量
struct sockaddr_in bindaddr;
bzero(&bindaddr,sizeof(bindaddr));
bindaddr.sin_family=AF_INET;
bindaddr.sin_addr.s_addr=htonl(INADDR_ANY); //绑定客户端自己的ip地址
bindaddr.sin_port=htons(10000); //绑定客户端自己的端口号
//定义结构体变量存放对方(服务器)的ip和端口号
struct sockaddr_in serveraddr;
bzero(&serveraddr,sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_addr.s_addr=inet_addr("192.168.24.3"); //服务器的ip地址
serveraddr.sin_port=htons(10086); //服务器的端口号
//创建tcp套接字
tcpsock=socket(AF_INET,SOCK_STREAM,0);
if(tcpsock==-1)
{
perror("创建tcp套接字!n");
return -1;
}
//设置端口重复使用
int on=1;
setsockopt(tcpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
//绑定ip和端口号
ret=bind(tcpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
if(ret==-1)
{
perror("绑定失败!n");
return -1;
}
//连接服务器
ret=connect(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
if(ret==-1)
{
perror("连接服务器!n");
return -1;
}
//创建线程专门接收服务器的信息
pthread_create(&id,NULL,routine,NULL);
//发送信息给服务器
while(1)
{
bzero(buf,100);
printf("请输入要发送给服务器的信息,按照如下格式输入!n");
printf("all:真实的信息--》群发!n");
printf("端口号:真实的信息--》点播!n");
scanf("%s",buf);
write(sockfd,buf,strlen(buf));
}
close(tcpsock);
return 0;
}
UDP单向通信
发送
#include "myhead.h"
int main()
{
char buf[100];
int ret;
int udpsock;
//定义ipv4地址结构体变量
struct sockaddr_in bindaddr;
bzero(&bindaddr,sizeof(bindaddr));
bindaddr.sin_family=AF_INET;
bindaddr.sin_addr.s_addr=htonl(INADDR_ANY); //绑定自己的ip地址
bindaddr.sin_port=htons(10086); //绑定自己的端口号
struct sockaddr_in otheraddr;
bzero(&otheraddr,sizeof(otheraddr));
otheraddr.sin_family=AF_INET;
otheraddr.sin_addr.s_addr=inet_addr("192.168.24.3"); //对方的ip
otheraddr.sin_port=htons(20000); //对方的端口号
//创建udp套接字
udpsock=socket(PF_INET,SOCK_DGRAM,0);
if(udpsock==-1)
{
perror("创建udp套接字!n");
return -1;
}
//设置端口重复使用
int on=1;
setsockopt(udpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
//绑定ip和端口号
ret=bind(udpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
if(ret==-1)
{
perror("绑定失败!n");
return -1;
}
//发送信息
while(1)
{
bzero(buf,100);
printf("请输入要发送的信息!n");
scanf("%s",buf);
sendto(udpsock,buf,strlen(buf),0,(struct sockaddr *)&otheraddr,sizeof(otheraddr));
}
}
接收
#include "myhead.h"
int main()
{
char buf[100];
char ip[16]={0};
int ret;
int udpsock;
//定义ipv4地址结构体变量
struct sockaddr_in bindaddr;
bzero(&bindaddr,sizeof(bindaddr));
bindaddr.sin_family=AF_INET;
bindaddr.sin_addr.s_addr=htonl(INADDR_ANY); //绑定自己的ip地址
bindaddr.sin_port=htons(20000); //绑定自己的端口号
struct sockaddr_in otheraddr;
bzero(&otheraddr,sizeof(otheraddr));
int size=sizeof(otheraddr);
//创建udp套接字
udpsock=socket(PF_INET,SOCK_DGRAM,0);
if(udpsock==-1)
{
perror("创建udp套接字!n");
return -1;
}
//设置端口重复使用
int on=1;
setsockopt(udpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
//绑定ip和端口号
ret=bind(udpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
if(ret==-1)
{
perror("绑定失败!n");
return -1;
}
//接收信息
while(1)
{
bzero(buf,100);
recvfrom(udpsock,buf,100,0,(struct sockaddr *)&otheraddr,&size);
printf("ip %s 端口是 %hu 这个人发送的信息是:%sn",inet_ntop(AF_INET,&(otheraddr.sin_addr.s_addr),ip,sizeof(ip)),ntohs(otheraddr.sin_port),buf);
}
}
UDP双向通信
#include "myhead.h"
int udpsock;
void *fun(void *arg)
{
struct sockaddr_in addr;
bzero(&addr,sizeof(addr));
int size=sizeof(addr);
char otherbuf[100];
while(1)
{
bzero(otherbuf,100);
recvfrom(udpsock,otherbuf,100,0,(struct sockaddr *)&addr,&size);
printf("对方发送过来的信息是:%sn",otherbuf);
}
}
int main()
{
pthread_t id;
char buf[100];
int ret;
//定义ipv4地址结构体变量
struct sockaddr_in bindaddr;
bzero(&bindaddr,sizeof(bindaddr));
bindaddr.sin_family=AF_INET;
bindaddr.sin_addr.s_addr=htonl(INADDR_ANY); //绑定自己的ip地址
bindaddr.sin_port=htons(10086); //绑定自己的端口号
struct sockaddr_in otheraddr;
bzero(&otheraddr,sizeof(otheraddr));
otheraddr.sin_family=AF_INET;
otheraddr.sin_addr.s_addr=inet_addr("192.168.24.3"); //对方的ip
otheraddr.sin_port=htons(20000); //对方的端口号
//创建udp套接字
udpsock=socket(PF_INET,SOCK_DGRAM,0);
if(udpsock==-1)
{
perror("创建udp套接字!n");
return -1;
}
//设置端口重复使用
int on=1;
setsockopt(udpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
//绑定ip和端口号
ret=bind(udpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
if(ret==-1)
{
perror("绑定失败!n");
return -1;
}
//线程专门接收信息
pthread_create(&id,NULL,fun,NULL);
//发送信息
while(1)
{
bzero(buf,100);
printf("请输入要发送的信息!n");
scanf("%s",buf);
sendto(udpsock,buf,strlen(buf),0,(struct sockaddr *)&otheraddr,sizeof(otheraddr));
}
}
#include "myhead.h"
int udpsock;
void *fun(void *arg)
{
struct sockaddr_in otheraddr;
bzero(&otheraddr,sizeof(otheraddr));
otheraddr.sin_family=AF_INET;
otheraddr.sin_addr.s_addr=inet_addr("192.168.24.3"); //对方的ip地址
otheraddr.sin_port=htons(10086); //对方的端口号
char buf[100];
while(1)
{
bzero(buf,100);
printf("请输入要发送的信息!n");
scanf("%s",buf);
sendto(udpsock,buf,strlen(buf),0,(struct sockaddr *)&otheraddr,sizeof(otheraddr));
}
}
int main()
{
pthread_t id;
char buf[100];
char ip[16]={0};
int ret;
//定义ipv4地址结构体变量
struct sockaddr_in bindaddr;
bzero(&bindaddr,sizeof(bindaddr));
bindaddr.sin_family=AF_INET;
bindaddr.sin_addr.s_addr=htonl(INADDR_ANY); //绑定自己的ip地址
bindaddr.sin_port=htons(20000); //绑定自己的端口号
struct sockaddr_in otheraddr;
bzero(&otheraddr,sizeof(otheraddr));
int size=sizeof(otheraddr);
//创建udp套接字
udpsock=socket(PF_INET,SOCK_DGRAM,0);
if(udpsock==-1)
{
perror("创建udp套接字!n");
return -1;
}
//设置端口重复使用
int on=1;
setsockopt(udpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
//绑定ip和端口号
ret=bind(udpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
if(ret==-1)
{
perror("绑定失败!n");
return -1;
}
//线程专门发送信息
pthread_create(&id,NULL,fun,NULL);
//接收信息
while(1)
{
bzero(buf,100);
recvfrom(udpsock,buf,100,0,(struct sockaddr *)&otheraddr,&size);
printf("ip %s 端口是 %hu 这个人发送的信息是:%sn",inet_ntop(AF_INET,&(otheraddr.sin_addr.s_addr),ip,sizeof(ip)),ntohs(otheraddr.sin_port),buf);
}
}
UDP广播
在这里插入代码片#include "myhead.h"
int main()
{
char buf[100];
int ret;
int udpsock;
//定义ipv4地址结构体变量
struct sockaddr_in bindaddr;
bzero(&bindaddr,sizeof(bindaddr));
bindaddr.sin_family=AF_INET;
bindaddr.sin_addr.s_addr=htonl(INADDR_ANY); //绑定自己的ip地址
bindaddr.sin_port=htons(10086); //绑定自己的端口号
struct sockaddr_in otheraddr;
bzero(&otheraddr,sizeof(otheraddr));
otheraddr.sin_family=AF_INET;
otheraddr.sin_addr.s_addr=inet_addr("192.168.24.255"); //广播专用地址
otheraddr.sin_port=htons(20000); //对方的端口号
//创建udp套接字
udpsock=socket(PF_INET,SOCK_DGRAM,0);
if(udpsock==-1)
{
perror("创建udp套接字!n");
return -1;
}
//设置端口重复使用
int on=1;
setsockopt(udpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
//绑定ip和端口号
ret=bind(udpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
if(ret==-1)
{
perror("绑定失败!n");
return -1;
}
//设置套接字的属性为可以广播
setsockopt(udpsock,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));
//发送广播信息
while(1)
{
bzero(buf,100);
printf("请输入要发送广播的信息!n");
scanf("%s",buf);
sendto(udpsock,buf,strlen(buf),0,(struct sockaddr *)&otheraddr,sizeof(otheraddr));
}
}
```cpp
#include "myhead.h"
int main()
{
char buf[100];
char ip[16]={0};
int ret;
int udpsock;
//定义ipv4地址结构体变量
struct sockaddr_in bindaddr;
bzero(&bindaddr,sizeof(bindaddr));
bindaddr.sin_family=AF_INET;
bindaddr.sin_addr.s_addr=htonl(INADDR_ANY); //绑定自己的ip地址
bindaddr.sin_port=htons(20000); //绑定自己的端口号
struct sockaddr_in otheraddr;
bzero(&otheraddr,sizeof(otheraddr));
int size=sizeof(otheraddr);
//创建udp套接字
udpsock=socket(PF_INET,SOCK_DGRAM,0);
if(udpsock==-1)
{
perror("创建udp套接字!n");
return -1;
}
//设置端口重复使用
int on=1;
setsockopt(udpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
//绑定ip和端口号
ret=bind(udpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
if(ret==-1)
{
perror("绑定失败!n");
return -1;
}
//接收信息
while(1)
{
bzero(buf,100);
recvfrom(udpsock,buf,100,0,(struct sockaddr *)&otheraddr,&size);
printf("ip %s 端口是 %hu 这个人发送的信息是:%sn",inet_ntop(AF_INET,&(otheraddr.sin_addr.s_addr),ip,sizeof(ip)),ntohs(otheraddr.sin_port),buf);
}
}
send和 recv
#include "myhead.h"
int main()
{
int tcpsock;
int ret;
char buf[100];
//定义ipv4地址结构体变量
struct sockaddr_in bindaddr;
bzero(&bindaddr,sizeof(bindaddr));
bindaddr.sin_family=AF_INET;
bindaddr.sin_addr.s_addr=htonl(INADDR_ANY); //绑定客户端自己的ip地址
bindaddr.sin_port=htons(10000); //绑定客户端自己的端口号
//定义结构体变量存放对方(服务器)的ip和端口号
struct sockaddr_in serveraddr;
bzero(&serveraddr,sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_addr.s_addr=inet_addr("192.168.24.3"); //服务器的ip地址
serveraddr.sin_port=htons(20000); //服务器的端口号
//创建tcp套接字
tcpsock=socket(AF_INET,SOCK_STREAM,0);
if(tcpsock==-1)
{
perror("创建tcp套接字!n");
return -1;
}
//绑定ip和端口号
ret=bind(tcpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
if(ret==-1)
{
perror("绑定失败!n");
return -1;
}
//连接服务器
ret=connect(tcpsock,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
if(ret==-1)
{
perror("连接服务器!n");
return -1;
}
//发送信息给服务器
while(1)
{
bzero(buf,100);
printf("请输入要发送给服务器的信息!n");
scanf("%s",buf);
send(tcpsock,buf,strlen(buf),0);
}
close(tcpsock);
return 0;
}
#include "myhead.h"
int main(int argc,char **argv)
{
int tcpsock;
int newsock;
int ret;
char buf[100];
//定义ipv4地址结构体变量
struct sockaddr_in bindaddr;
bzero(&bindaddr,sizeof(bindaddr));
bindaddr.sin_family=AF_INET;
bindaddr.sin_addr.s_addr=htonl(INADDR_ANY); //绑定服务器自己的ip地址
bindaddr.sin_port=htons(20000); //绑定服务器自己的端口号
struct sockaddr_in clientaddr;
bzero(&clientaddr,sizeof(clientaddr));
int addrsize=sizeof(clientaddr);
//创建tcp套接字
tcpsock=socket(AF_INET,SOCK_STREAM,0);
if(tcpsock==-1)
{
perror("创建tcp套接字!n");
return -1;
}
printf("旧的文件描述符:%dn",tcpsock);
//setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
//绑定ip和端口号
ret=bind(tcpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
if(ret==-1)
{
perror("绑定失败!n");
return -1;
}
//监听
ret=listen(tcpsock,8);
if(ret==-1)
{
perror("监听失败!n");
return -1;
}
//接收客户端的连接请求
newsock=accept(tcpsock,(struct sockaddr *)&clientaddr,&addrsize);
if(newsock==-1)
{
perror("接收客户端的连接请求失败!n");
return -1;
}
printf("新的文件描述符:%dn",newsock);
//接收信息
while(1)
{
bzero(buf,100);
//ret=recv(newsock,buf,100,0);
ret=recv(newsock,buf,100,MSG_WAITALL); //强行要求recv按照100个字节接收数据,没有100个字节就阻塞等待
printf("recv的返回值是:%dn",ret);
printf("客户端发送给我的信息是:%sn",buf);
}
}



