linux通信程序客户端,linux网络编程之用socket实现简单客户端和服务端的通信(基于UDP)...

1、sendto和recvfrom函数介绍

sendto(经socket传送数据)

相关函数

send , sendmsg,recv , recvfrom , socket

表头文件

#include < sys/types.h >

#include < sys/socket.h >

定义函数

int sendto ( int 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的结果长度。

返回值

成功则返回实际传送出去的字符数,失败返回-1,错误原因存于errno 中。

错误代码

EBADF 参数s非法的socket处理代码。

EFAULT 参数中有一指针指向无法存取的内存空间。

WNOTSOCK canshu s为一文件描述词,非socket。

EINTR 被信号所中断。

EAGAIN 此动作会令进程阻断,但参数s的soket为补课阻断的。

ENOBUFS 系统的缓冲内存不足。

EINVAL 传给系统调用的参数不正确。

recvfrom(经socket接收数据)

相关函数

recv,recvmsg,send,sendto,socket

表头文件

#include

#include

定义函数

int recvfrom(int 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,错误原因存于errno中。

错误代码

EBADF 参数s非合法的socket处理代码

EFAULT 参数中有一指针指向无法存取的内存空间。

ENOTSOCK 参数s为一文件描述词,非socket。

EINTR 被信号所中断。

EAGAIN 此动作会令进程阻断,但参数s的socket为不可阻断。

ENOBUFS 系统的缓冲内存不足

ENOMEM 核心内存不足

EINVAL 传给系统调用的参数不正确。

2、单客户端和服务端的通信(基于UDP)   图解

0818b9ca8b590ca3270a3433284dd417.png

3、单客户端和服务端的通信(基于UDP)   代码

1、服务端代码socket3.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define PORT 8888

#define MAX_MSG_SIZE 1024

int main(void)

{

int sockfd, addrlen, n;

struct sockaddr_in addr;

char msg[MAX_MSG_SIZE];

sockfd = socket(AF_INET, SOCK_DGRAM, 0);

if (sockfd < 0)

{

fprintf(stderr, "socket failed\n");

exit(EXIT_FAILURE);

}

addrlen = sizeof(struct sockaddr_in);

bzero(&addr, addrlen);

addr.sin_family = AF_INET;

addr.sin_addr.s_addr = htonl(INADDR_ANY);

addr.sin_port = htons(PORT);

if (bind(sockfd, (struct sockaddr*)(&addr), addrlen) < 0)

{

fprintf(stderr, "bind fail\n");

exit(EXIT_FAILURE);

}

puts("bind success");

while (1)

{

bzero(msg, MAX_MSG_SIZE);

n = recvfrom(sockfd, msg, sizeof(msg), 0, (struct sockaddr *)(&addr), &addrlen);

fprintf(stdout, "Recevie message from client is %s\n", msg);

fgets(msg, MAX_MSG_SIZE,stdin);

printf("Server endpoint input message %s\n", msg);

sendto(sockfd, msg, n, 0,(struct sockaddr *)(&addr), addrlen);

}

close(sockfd);

exit(EXIT_SUCCESS);

}

2、客户端代码socket4.c

#include

#include

#include

#include

#include

#include

#include

#define MAX_BUF_SIZE 1024

#define PORT 8888

int main()

{

int sockfd, addrlen, n;

char buffer[MAX_BUF_SIZE];

struct sockaddr_in addr;

sockfd = socket(AF_INET, SOCK_DGRAM, 0);

if (sockfd < 0)

{

fprintf(stderr, "socket falied\n");

exit(EXIT_FAILURE);

}

addrlen = sizeof(struct sockaddr_in);

bzero(&addr, addrlen);

addr.sin_family = AF_INET;

addr.sin_port = htons(PORT);

addr.sin_addr.s_addr = htonl(INADDR_ANY);

puts("socket success");

while(1)

{

bzero(buffer, MAX_BUF_SIZE);

fgets(buffer, MAX_BUF_SIZE, stdin);

sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr *)(&addr), addrlen);

printf("client send msg is %s\n", buffer);

n = recvfrom(sockfd, buffer, strlen(buffer), 0, (struct sockaddr *)(&addr), &addrlen);

fprintf(stdout, "clinet Receive message from server is %s\n", buffer);

}

close(sockfd);

exit(0);

return 0;

}

4、运行结果

0818b9ca8b590ca3270a3433284dd417.png

5、总结

服务端:socket->bind->(sendto 、revcfrom)

客户端:socket->(sendto 、revcfrom)

upd不是面相连接的,这个是和tcp本质区别,数据可能会乱序,重复。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值