linux+udp数据传输,Linux利用socket实现两台pc之间的数据传输功能,包括windows到linux,UDP实现...

makefile 和TCP一样,参见上一篇博文

客户端和服务端主函数也和上一篇的tcp是一样的,同样参考上一篇博文,这里只是修改了pub.c的文件了

/*

* pub.c

*

* Created on: 2016年7月14日

* Author: Administrator

*/

#ifdef WIN

#include

#else

#include

#include

#include

#include

#include

#include

#define SOCKET int

#endif

#include

#include "pub.h"

#define BUFSIZE 262144 //1024 * 256

void getfilename(const char *filename, char *name)

{

int len = strlen(filename);

int i;

for (i = (len - 1); i >= 0; i--)

{

if ((filename[i] == '\\') || (filename[i] == '/'))

{

break;

}

}

strcpy(name, &filename[i + 1]);

}

int init_socket()

{

// 如果是windows,执行如下代码

#ifdef WIN

WORD wVersionRequested;

WSADATA wsaData;

int err;

wVersionRequested = MAKEWORD(1, 1);

err = WSAStartup(wVersionRequested, &wsaData);

if (err != 0)

{

return -1;

}

if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)

{

WSACleanup();

return -1;

}

#endif

return 0;

}

SOCKET create_send_socket()// 建立發送數據的udp socket

{

if (init_socket() == -1)

return 0;

SOCKET st = socket(AF_INET, SOCK_DGRAM, 0);// 建立UDP socket

if (st == 0)

return 0; // 如果建立socket失敗,返回0

return st; // udp socket建立成功,返回socket描述符

}

SOCKET create_recv_socket(int port)

{

SOCKET st = socket(AF_INET, SOCK_DGRAM, 0);// 建立UDP socket

if (st == 0)

return 0;

struct sockaddr_in addr;

memset(&addr, 0, sizeof(addr));

addr.sin_family = AF_INET;

addr.sin_port = htons(port);

addr.sin_addr.s_addr = htonl(INADDR_ANY);

if (bind(st, (struct sockaddr*)&addr, sizeof(addr)) == -1)

{

printf("bind failed %s\n", strerror(errno));

return 0;

}

return st;// udp

}

// 连接到hostname指定的IP地址和port指定的端口号

int send_work(const char *hostname, int port, const char *filename)

{

SOCKET st_send = create_send_socket();// 建立发送数据的UDP Socket

SOCKET st_recv = create_recv_socket(port + 1);// 建立接受数据的UDP Socket

if (st_send == 0) // 建立失败,函数返回

{

return 0;

}

if (st_recv == 0) // 建立失败,函数返回

{

return 0;

}

FILE *fd = fopen(filename, "rb"); // 以只读方式打开filename指定的文件

if (fd == NULL) // 如果打开文件失败,函数返回

{

printf("open %s failed %s\n", filename, strerror(errno));

return 0;

}

char *buf = malloc(BUFSIZE); // 申请一个缓冲区,存放接收到的文件内容

memset(buf, 0, BUFSIZE);

// 从完整路径名中解析出文件名称

getfilename(filename, buf);

struct sockaddr_in addr;

memset(&addr, 0, sizeof(addr));

addr.sin_family = AF_INET;

addr.sin_port = htons(port);

addr.sin_addr.s_addr = inet_addr(hostname);

// 客戶端第一次給server端發送文件名

size_t rc = sendto(st_send, buf, strlen(buf), 0, (struct sockaddr *)&addr, sizeof(addr)); // 客户端第一次给server端发送的数据为要传递的文件名

if (rc <= 0)

{

printf("send failed %s\n", strerror(errno));

}

else

{

struct sockaddr_in client_addr;

#ifdef WIN

int len = 0;

#else

unsigned int len 0;

#endif

len = sizeof(client_addr);

memset(&client_addr, 0, sizeof(client_addr));

memset(buf, 0, BUFSIZE);

if (recvfrom(st_recv, buf, BUFSIZE, 0,

(struct sockaddr *)&client_addr, &len) <= 0) // 接受来自server端的回复

{

printf("recv failed %s\n", strerror(errno));

}

else

{

if (strncmp(buf, "OK", 2) == 0)

{

while(1)

{

memset(buf, 0, BUFSIZE);

rc = fread(buf, 1, BUFSIZE, fd);

if (rc <= 0)

{

break;//

}

else

{

rc = sendto(st_send, buf, rc, 0, (struct aockaddr *)&addr, sizeof(addr));

if (rc <= 0)

{

printf("send failed %s\n", strerror(errno));

break;

}

}

}

}

memset(buf, 0, BUFSIZE);

// 連發128字節0,代表文件發送完畢

rc = sendto(st_send, buf, 128, 0, (struct aockaddr *)&addr, sizeof(addr));

}

}

fclose(fd);

free(buf);

#ifdef WIN

closesocket(st_send);

closesocket(st_recv);

WSACleanup();

#else

close(st_send);

close(st_recv);

#endif

return 1;

}

// server端socket在port指定的断口上listen,接收来自client发送的文件

int recv_work(int port)

{

SOCKET st_send = create_send_socket();// 建立发送数据的UDP Socket

SOCKET st_recv = create_recv_socket(port);// 建立接受数据的UDP Socket

if (st_send == 0) // 建立失败,函数返回

{

return 0;

}

if (st_recv == 0) // 建立失败,函数返回

{

return 0;

}

char *buf = malloc(BUFSIZE);

FILE *fd = NULL;

#ifdef WIN

int len = 0;

#else

unsigned int len = 1;

#endif

struct sockaddr_in client_addr;

len = sizeof(client_addr);

memset(&client_addr, 0, sizeof(client_addr));

memset(buf, 0, BUFSIZE);

// 接收来自client的数据,客户端第一次发送的文件名

size_t rc = recvfrom(st_recv, buf, BUFSIZE, 0, (struct sockaddr *)&client_addr, &len);

if (rc <= 0)

{

printf("recv failed %s\n", strerror(errno));

}

else

{

printf("receiving %s\n", buf);

fd = fopen(buf, "wb");// 以只写方式打开文件

if (fd == NULL)

{

printf("open %s failed %s\n", buf, strerror(errno));

}

else

{

client_addr.sin_port = htons(port + 1);

memset(buf, 0, BUFSIZE);

strcpy(buf, "OK");

rc = sendto(st_send, buf, strlen(buf), 0, (struct *)&client_addr, sizeof(client_addr)); // 回复客户端,同意接收文件

if (rc <= 0)

{

printf("send failed %s\n", strerror(errno));

}

while (1)

{

memset(buf, 0, BUFSIZE);

rc = recvfrom(st_recv, buf, BUFSIZE, 0, (struct *)&client_addr, &len);// 循环接收来自client的数据,数据为发送文件的内容

char tmp[128];

memset(tmp, 0, sizeof(tmp));

if (memcmp(buf, tmp, sizeof(tmp)) == 0)

{

break;

}

if (rc <= 0)// 如果client连接断开,代表文件传递完成,或者网络意外中断,循环break

{

printf("recv failed %s\n", strerror(errno));

break;

}

else

{

fwrite(buf, 1, rc, fd);// 将从client端收到的内容写入文件

}

}

}

}

if (fd)

fclose(fd);

free(buf);

#ifdef WIN

closesocket(st_send);

closesocket(st_recv);

WSACleanup();

#else

close(st_send);

close(st_recv);

#endif

return 1;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值