server.c:
#include <stdlib.h>
#include <stdio.h>#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>
#define SERVER_PORT 8888 //定义端口号:(0-1024为保留端口号,最好不要用)
#define MAX_MSG_SIZE 1024
void udps_respon(int sockfd)
{
struct sockaddr_in addr;
int addrlen;
int n;
char msg[MAX_MSG_SIZE];
while(1)
{ /* 从网络上读,并写到网络上 */
bzero(msg, sizeof(msg)); // 初始化,清零
addrlen = sizeof(struct sockaddr);
n = recvfrom(sockfd, msg, MAX_MSG_SIZE, 0, (struct sockaddr*)&addr, &addrlen); // 从客户端接收消息
/*函数原型:int recvfrom(SOCKET s,void *buf,int len,unsigned int flags, struct sockaddr *from,int *fromlen); 函数说明:recv()用来接收远程主机经指定的socket传来的数据,并把数据传到由参数buf指向的内存空间,参数len为可接收数据的最大长度.参数flags一般设0,其他数值定义参考recv().参数from用来指定欲传送的网络地址,结构sockaddr请参考bind()函数.参数fromlen为sockaddr的结构长度.返回值:成功则返回接收到的字符数,失败返回-1.*/
msg[n]=0;
/* 显示服务端已经收到了信息 */
fprintf(stdout,"Server have received %s", msg); // 显示消息
}
}
int main(int argc, char **argv)
{
int sockfd; //socket描述符
struct sockaddr_in addr; //定义服务器起地址
/* 服务器端开始建立socket描述符 */
sockfd=socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd<0)
{
fprintf(stderr, "Socket Error:%s\n", strerror(errno));
exit(1);
}
/* 服务器端填充 sockaddr结构 */
bzero(&addr, sizeof(struct sockaddr_in)); // 初始化,置0
addr.sin_family=AF_INET; // Internet
addr.sin_addr.s_addr=htonl(INADDR_ANY); // (将本机器上的long数据转化为网络上的long数据)和任何主机通信 //INADDR_ANY 表示可以接收任意IP地址的数据,即绑定到所有的IP
//addr.sin_addr.s_addr=inet_addr("192.168.1.1"); //用于绑定到一个固定IP,inet_addr用于把数字加格式的ip转化为整形ip
addr.sin_port=htons(SERVER_PORT); // (将本机器上的short数据转化为网络上的short数据)端口号
/* 捆绑sockfd描述符 */
if(bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in))<0)
{
fprintf(stderr, "Bind Error:%s\n", strerror(errno));
exit(1);
}
udps_respon(sockfd); // 进行读写操作
close(sockfd);
}
client.c:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>
#define SERVER_PORT 8888 //定义端口号:(0-1024为保留端口号,最好不要用)
#define MAX_BUF_SIZE 1024
void udpc_requ(int sockfd,const struct sockaddr_in *addr,int len)
{
int n;
char buffer[MAX_BUF_SIZE];
while(1)
{
/* 从键盘读入,写到服务端 */
printf("Please input char:\n");
fgets(buffer,MAX_BUF_SIZE,stdin)
sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr*)addr, len);
/* int sendto ( socket s , const void * msg, int len, unsigned int flags, const struct sockaddr * to , int tolen ) ; sendto() 用来将数据由指定的socket传给对方主机。参数s为已建好连线的socket,如果利用UDP协议则不需经过连线操作。参数msg指向欲连线的数据内容,参数flags 一般设0,详细描述请参考send()。参数to用来指定欲传送的网络地址,结构sockaddr请参考bind()。参数tolen为sockaddr的结构长度。*/
bzero(buffer, MAX_BUF_SIZE);
}
close(fd);
}
int main(int argc,char **argv)
{
int sockfd; //socket描述符
struct sockaddr_in addr; //定义服务器起地址
if(argc!=2)
{
fprintf(stderr, "Usage:%s server_ip\n", argv[0]);
exit(1);
}
/* 建立 sockfd描述符 */
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd<0)
{
fprintf(stderr, "Socket Error:%s\n", strerror(errno));
exit(1);
}
/* 填充服务端的资料 */
bzero(&addr, sizeof(struct sockaddr_in)); // 初始化,置0
addr.sin_family=AF_INET; // Internet
addr.sin_port=htons(SERVER_PORT);// (将本机器上的short数据转化为网络上的short数据)端口号
if(0==inet_aton(argv[1], &addr.sin_addr)) /*inet_aton函数用于把字符串型的IP地址转化成网络2进制数字*/
/* int inet_aton(const char *string, struct in_addr*addr); 参数描述:
1 输入参数string包含ASCII表示的IP地址。
2 输出参数addr是将要用新的IP地址更新的结构。
返回值:
如果这个函数成功,函数的返回值非零,如果输入地址不正确则会返回零。使用这个函数并没有错误码存放在errno中,所以它的值会被忽略。*/
{
fprintf(stderr, "Ip error:%s\n", strerror(errno));
exit(1);
}
udpc_requ(sockfd, &addr, sizeof(struct sockaddr_in)); // 进行读写操作
close(sockfd);
}