首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

linux socket编程的有关问题

2012-02-21 
linux socket编程的问题linuxsocket编程,怎样才能实现一个基本的聊天程序,可以聊天,也可以发文件?希望达人

linux socket编程的问题
linux   socket编程,怎样才能实现一个基本的聊天程序,可以聊天   ,也可以发文件?希望达人指导~最好能贴出源码~

[解决办法]
这东东可大可小,你把要求说详细点。
[解决办法]
这是UDP传文件的一个sever端的程序:仅供参考:
如果改成Linux下,只需要改其中的一小部分就可以了。。。就是初始化那一些。。。

/******************************************************************
*FILENAME: sever.cpp
*DESCRIPTION: 本文件用来接收一个UDP传输来的文件 , 并且可以保证可靠
性传输.
*AUTHOR: roading
*DATE: 2007-4-12
*****************************************************************/
#include <stdio.h>
#include <winsock2.h>
#include <string.h>
#include <winbase.h>
#include <process.h>
#include <time.h>
#include <conio.h>

#define BUFLEN20460//除去五个标志位和一个结束符,其它的都可以用来传输数据
#define ADDR "192.168.6.106 "
#define SRVPORT8026//服务器端口号
#define CILPORT 8025//客户端端口号
#define FILE_SEND_END 633
#define SENDLEN 6//发送数据长度
#define PIONIT_NULL 100 //错误号,指针为空
#define SENDNUM 500 //最多重发的次数

time_t BeginTime, EndTime, UsrTime;

int GetID(char *); //获得报文的ID号
void SetID(char *,int); //设定报文的ID号

int main()
{

int Timer2 = SENDNUM;
WSAData wsadata;
FILE *frecv;
sockaddr_in clientaddr, srvaddr;
SOCKET s;
int nRc, clientlen = sizeof(clientaddr), Serial = 0 ,ACKnum = 0;
char RecvBuf[BUFLEN] = {0} ,SendBuf[SENDLEN];


//初始化winsocket
nRc = WSAStartup(MAKEWORD(2, 2), &wsadata);
if(nRc)
{
printf( "error in init the winsock \n ");
return ERROR_NO_NETWORK;
}
printf( "winsock initialized!\n ");

//创建udp socket
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == INVALID_SOCKET)
{
printf( "socket create error!\n ");
WSACleanup();
return ERROR_NO_NETWORK;
}
printf( "socket created sucess!\n ");

//绑定一个本地端口
srvaddr.sin_family = AF_INET;
srvaddr.sin_port = htons(SRVPORT);
srvaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
nRc = bind(s, (LPSOCKADDR)&srvaddr, sizeof(srvaddr));


if (nRc == SOCKET_ERROR)
{
printf( "port bind error !\n ");
closesocket(s);
WSACleanup();
return ERROR_NO_NETWORK;
}
printf( "port bind ok !\n ");


clientaddr.sin_family = AF_INET;
clientaddr.sin_port = htons(CILPORT);
clientaddr.sin_addr.S_un.S_addr = inet_addr(ADDR);

frecv = fopen( "recv ", "wb ");
if (frecv == NULL)
{
printf( " file open error !\n ");
}

unsigned long K = 1;
SetID(SendBuf, ACKnum);
time(&BeginTime);
printf( "请确认客户端是开放的, 按任意键开始传输\n ");
getch();
printf( "文件传输开始,开始时间:%s\n ", ctime(&BeginTime));
//向服务器端发送数据
while (1)
{

//清空缓冲区
memset(RecvBuf, '\0 ',BUFLEN);

//设置非阻塞模式
ioctlsocket(s,FIONBIO,&K);


nRc = recvfrom(s, RecvBuf, BUFLEN, 0, (SOCKADDR *)&clientaddr, &clientlen);

//判断是否已经重传到最大次数
if (Timer2 == 0)
{
printf( "文件传输失败,网络断开或者对方终止传输 \n ");
return ERROR_NETWORK_UNREACHABLE;
}

//判断是否接收成功
if (RecvBuf[0] != '\0 ')
{
Timer2 = SENDNUM;

Serial = GetID(RecvBuf);
//如果接收的不是ACKnum,重发
if (Serial != ACKnum)
{


SetID(SendBuf, ACKnum);
sendto(s, SendBuf, sizeof(SendBuf), 0, (SOCKADDR *)&clientaddr, sizeof(clientaddr) );

}
else
{
//判断是否到文件尾
if (strlen(RecvBuf) == 5)
{
time(&EndTime);
printf( "文件传输成功 !\n ");
printf( "用时:%s\n ",ctime(&EndTime));

//结束,发送两次结束信号
SetID(SendBuf,99999);
sendto(s, SendBuf, sizeof(SendBuf), 0, (SOCKADDR *)&clientaddr, sizeof(clientaddr) );
sendto(s, SendBuf, sizeof(SendBuf), 0, (SOCKADDR *)&clientaddr, sizeof(clientaddr) );
closesocket(s);
WSACleanup();
fclose(frecv);
return FILE_SEND_END;
}
else
{
//写入到文件,并且ACK加1,发送
fwrite(RecvBuf + 5, sizeof(char), strlen(RecvBuf) - 6, frecv);
ACKnum++;
SetID(SendBuf, ACKnum);
sendto(s, SendBuf, sizeof(SendBuf), 0, (SOCKADDR *)&clientaddr, sizeof(clientaddr) );
}
}

}
//没有数据到,重发,并且启动计数器
else
{
Timer2--;
sendto(s, SendBuf, sizeof(SendBuf), 0, (SOCKADDR *)&clientaddr, sizeof(clientaddr) );
Sleep(20);
}

}
}


/**************************************************************
FUNCTION:setID
DESCRIPTION:根据序列号,设定ACK的序号
INPUT:int i ,序列号
OUTPUT:设定后存入 SendBuf
RETURN:void
**************************************************************/
void SetID(char *SendBuf,int i)
{
memset(SendBuf, '\0 ',SENDLEN);
int j = 0, temp = i;
while (temp/10)
{
j++;
temp = temp/10;
}
j++;

for (temp = 0; temp < 5-j; temp++)
{
SendBuf[temp] = '0 ';
}
sprintf(SendBuf + 5-j, "%d ",i);

}

/**************************************************************
FUNCTION:GetID
DESCRIPTION:根据接收缓冲区,获得序号
INPUT:SendBuf 缓冲区数据
OUTPUT:N/A
RETURN:序号
**************************************************************/

int GetID(char *SendBuf)
{
//判断SendBuf
if (SendBuf == NULL)
{
return PIONIT_NULL;
}
char temp[6] = {0};
int i = 0;
for(i = 0;i < 5 ;i++)
{
temp[i] = SendBuf[i];
}

return strtol(temp, NULL, 10);

}
[解决办法]
首先建立协议, 规范发送和传输的数据格式.
然后根据数据格式, 确定是聊天还是发文件.
最后进行相应处理.

热点排行