linux基于socket下的简单聊天室

linux基于socket下的简单聊天室
linux基于socket下的简单聊天室

Linux操作系统与程序设计课程设计B报告书

姓名:

学号:

班级:

专业:

指导老师:郭玉华

计算机学院

时间:2013年7月5日

一、课程设计目的

本次课设主要是为了加强对Linux系统下的编程的各种知识点的整合与灵活运用,让我们更加熟悉Linux下的编程操作。重点在Linux下socket编程,了解TCP、UDP等协议的使用,并完成课设题目。

二、课程设计的实验环境

硬件:PC机两台以上

软件:LINUX系统 VIM编译器, Fedora

三、课程设计总体要求

1.在LINUX下实现网络聊天,包括公聊、一对多私聊等功能;

2.实现客户端之间经网络传输文件;

3.保存聊天记录,以备必要时查询。

系统功能

系统主要实现4大聊天室功能:

1.注册与登录系统

2.公聊

3.私聊

4.文件传输

模块调用关系

各模块间调用关系如图2-2所示:

图2-2 各模块间调用关系功能需求与系统模块的关系

实现原理

一、注册、登陆实现原理服务器端

服务器端建立好socket,等待连接,当客户端连接服务器,服务器接收连接,并接受客户端发送过来的消息,根据接收到的结构体所携带的协议来做相应的功能。服务器端启动后如图3-1所示:

图3-1 服务器端界面

1、注册:如果协议为reg,则为客户端注册,首先将发送过来的结构体,提取用户名和密码,然后需要对用户名合法性检验,验证之后如果用户名合法则将用户信息保存到文件中,合法性的规则包括用户名不能重复和不能使用all等协议作为用户名,并且用户名和密码都不能为空。如果注册成功,服务器端发送一个消息给注册的客户端,同样将消息保存在一个结构体里。如果失败,也给客户端发送一个消息如“您输入的用户名不能为all”或者“用户名XX已经存在”。注册结果如图3-2所示。

图3-2 注册新用户

2、登录:如果协议为login,则将用户名和密码信息提取,再遍历存放用户信息文件里的用户名和密码,直到验证成功为止,如果验证成功则对所有在线的用户发送一条消息:“提示XX用户登录成功”;如果失败则只给登陆失败的客户端提示登录失败,并给出原因,如“用户名不存在”或者“用户名或者密码输入错误”,并跳转到相应的代码执行其他功能,成功则等待发送客户端消息,失败则关闭socket并结束线程,如图3-3所示\

图3-3 用户登录

3、监听和踢出客户端:通过查看和修改绑定的socket和在线用户队列实现查看和踢出在线用户,提出用户后向被踢出用户发送相关信息,如图3-4所示。

图3-4 显示当前在线用户

这里从服务器端发回给客户端的消息使用sprintf到一个字符串来发送。

客户端

客户端的输入和消息的显示要使用2个终端,一个client,一个是Display。Client终端为输入的界面,在这个界面里,新建一个线程来接受服务器端发来的消息,再添加时间信息,并将这些信息写入文件,然后给Display进程发送一个消息,Display进程接到消息,就去读取文件,并将这些数据显示在Display终端。打开客户端Display终端界面,用lseek将内部指针指向文件末尾,等待Client终端里的线程将消息写入文件。一旦有消息过来,就去文件里读取数据并打印在Display终端。

打开客户端Client终端界面,有3个菜单,一个注册、一个登陆、一个退出,选择相应项即可进行相关操作,注册和登录如图

服务器端客户端发送给服务器端使用的协议:

1、all$msg,为给所有人发送消息。

2、直接输入view$获得在线用户列表。

3、who$msg,给用户名为“who”的用户发送私聊消息。

4、trans$who$filename将文件传输给who。

5、reg为注册。

6、login为登陆。

私聊实现原理

一、客户端

可以使用who$msg的形式发送私聊信息,意味着,这个消息是发送给who的。

或者,先使用who$来切换到发送私聊消息,这个时候,你不需要加上协议,即可给who这个用户发送消息,如图3-7、图3-8所示:

图3-7 e向q发信息

图3-8 q收到e发来的消息

当然,上述方法也可实现一对多聊天,如图3-9所示:

图3-9 一对多聊天

这些消息都加上协议who来封装成结构体,再发送给服务器端。

二、服务器端

如果是私聊,则根据客户端要发送到哪个用户名的用户,到链表里取得该用户名的客户端信息,服务器再发送给相应的接受信息的客户端。接受信息的客户终端就会先将信息保存到聊天记录的文件里,并显示接收到的信息,并且信息前面会显示相应的提示符。

公聊实现原理

一、客户端

客户端在登陆成功之后,默认就是all协议,可以直接发送公聊信息,不需要加上任何的协议,实现对所有人的人进行聊天。

命令为all$msg,给所有人发送消息。

或者先使用all$来切换到给所有人发送消息,切换后,不需要加上协议即可发送了,如图3-10、图3-11所示:

图3-10 xdy发送公聊信息

图3-11 各用户接收q的公聊信息

这些消息都根据协议来封装成结构体,再发送给服务器端。

二、服务器端

如果是私聊,则根据客户端要发送到哪个用户名的用户,到链表里取得该用户名的客户端信息,服务器再发送给相应的接受信息的客户端。接受信息的客户终端就会先将信息保存到聊天记录的文件里,并显示接收到的信息,并且信息前面会显示相应的提示符。

文件传输实现原理

一、客户端

如果某个客户端想发送文件给其他客户端,则直接使用命令trans$who$filename。Filename包括本地的路径和文件名。

Trans为协议,就是标志为传输文件。

Who就是发送给谁。

Filename就是要发送的文件在本地的文件名。发送和接收文件如图3-12、图3-13所示:

图3-12

注册与登录系统实现

1、注册的时候与服务器的交互过程:

请输入你的用户名:******

请输入密码:******

you pass : ******

请再次输入密码:******

pass you : ******

正在等待服务器应答...

接到服务器发来的信息:注册成功!

2、登陆的时候与服务器的交互过程:

请输入你的用户名:******

请输入密码:******

正在等待服务器应答...

接到服务器发来的信息:登录失败!

您还有2次机会,之后将退出程序!

请输入你的用户名:******

请输入密码:******

正在等待服务器应答...

接到服务器发来的信息:登录成功!

3、退出:

关闭socket,退出程序。

聊天功能实现

1、两个用户在私聊功能

who$:********(聊天内容)****

Who就是发送给谁。

2、公聊功能

all$:********(聊天内容)****

功能实现展示如下图4-3-1所示:

传输文件功能实现

使用trans$who$filename格式传送文件:

Filename包括本地的路径和文件名。

Trans为协议,就是标志为传输文件。

Who就是发送给谁。

Filename就是要发送的文件在本地的文件名。

总结

本次课程设计顺利完成了LINUX下聊天室工具的设计,包括注册、登记,私聊,公聊(群聊),传送文件等功能,送文件时可以传送文本。通过本次课程设计,我的软件开发能力在一定程度上提高了,对LINUX程序设计这一门课程也有了比较深刻的了解。实验过程中遇到了很多问题,刚开始对于shell一些简单的编程都不是很熟悉,通过去图书馆查阅资料,询问老师和同学,上网查阅资料,才得以解决各个问题,这个设计基本上完成了老师要求的公聊,私聊以及文件传输,但是由于自己能力的有限,没能做出一个窗体,让系统更完美化,这还西药以后的继续努力。

附录

/******check.h******/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MAXLEN 1024

struct message

{

char flag[15];

char name[10];

int size;

char msg[MAXLEN];

};

int reg_check(struct message *recievemsg); int login_check(struct message *recievemsg);

/******check.c******/

#include "check.h"

int reg_check(struct message *recievemsg)

{

int fd;

int read_size,write_size;

struct message cmpmsg;

if(strlen(recievemsg->name)>10 || strlen(recievemsg->msg)>20 )

{

return 1;

}

if(strcmp(recievemsg->name,"all")==0)

{

return -1;

}

if(strcmp(recievemsg->name,"reg")==0)

{

return -1;

}

if(strcmp(recievemsg->name,"login")==0)

{

return -1;

}

if(strcmp(recievemsg->name,"trans")==0)

{

return -1;

}

if((fd=open("user.txt",O_RDWR|O_CREAT|O_A PPEND,0666))<0)

{

perror("open");

printf("open\n");

return -2;

}

do

{

if((read_size=read(fd,&cmpmsg,sizeof(cmpmsg))) < 0)

{

perror("read");

close(fd);

return -2;

}

if(read_size != sizeof(struct message) && read_size !=0)

{

close(fd);

return -2;

}

if(strcmp(recievemsg->name,https://www.360docs.net/doc/bd2144528.html,)==0) {

close(fd);

return -1;

}

}while(read_size == sizeof(struct message));

if((write_size=write(fd,recievemsg,sizeof(struct message)))<0)

{

perror("write");

close(fd);

return -2;

}

while(write_size!=sizeof(struct message))

{

//write_size = 0-writesize;

lseek(fd,-write_size,SEEK_CUR);

write_size=write(fd,recievemsg,sizeof(struct message));

}

printf("write file success\n");

close(fd);

return 0;

}

int login_check(struct message *recievemsg)

{

int fd;

struct message cmpmsg;

int read_size;

if((fd=open("user.txt",O_RDONL Y))<0)

{

perror("open");

return -2;

}

do

{

if((read_size=read(fd,&cmpmsg,sizeof(struct message)))<0)

{

perror("read");

close(fd);

return -2;

}

if(read_size != sizeof(struct message) && read_size!=0)

{

close(fd);

return -2;

}

if((strcmp(recievemsg->name,https://www.360docs.net/doc/bd2144528.html,)==0 )&&(strcmp(recievemsg->msg,cmpmsg.msg)==0)) {

close(fd);

return 0;

}

}while(read_size>0);

close(fd);

return -1;

}

/*

void main()

{

struct message sendmsg;

printf("input name:\n");

gets(https://www.360docs.net/doc/bd2144528.html,);

printf("input mima:\n");

gets(sendmsg.msg);

printf("%d\n",reg_check(&sendmsg));

//

printf("%d\n",login_check(&sendmsg));

}

*/

/******client.c******/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include #include

#define MAXLEN 1024

struct message

{

char flag[15];

char name[10];

int size;

char msg[MAXLEN];

};

struct msq

{

long msg_type;

char msg_text[5];

};

int qid = -1,fd = -1,sockfd,savefilefd=-1;

char filefromname[10];

void handleQuit(int signal_no)

{

if(fd > 0)

close(fd);

close(sockfd);

if(qid > 0)

{

if((msgctl(qid,IPC_RMID,NULL))<0)

{

printf("消息队列无法关闭\n");

exit(1);

}

}

close(savefilefd);

printf("程序正常退出\n");

raise(SIGQUIT);

}

void cutStr(char str[],char left[],int n,char right[],int m,char c)

{

int i,k,j;

for(i = 0 ; i < n ;i++)

{

if(str[i] == c)

break;

}

if(i == n)

{

i = -1;

}

else

{

memset(left,0,strlen(left));

for(k = 0 ; k < i ; k++)

{

left[k] = str[k];

}

}

for(j = i+1 ; j < m;j++)

{

if(str[j] == '\0')

break;

right[j-i-1] = str[j];

}

left[i] = '\0';

if(j < m)

right[j-i-1] = '\0';

else

right[m] = '\0';

}

void handlesendfile(void)

{

struct message filedata;

//printf("filefromname = %s \n",filefromname);

do

{

memset(filedata.msg,0,sizeof(filedata.msg));

filedata.size = read(savefilefd,filedata.msg,1000);

strcpy(filedata.flag,"transf");

strcpy(https://www.360docs.net/doc/bd2144528.html,,filefromname);

if (filedata.size == 0)

{

printf("文件传输完毕\n");

strcpy(filedata.msg,"end$");

}

else if (filedata.size > 0)

{

printf("filedata.msg = %s\n",filedata.msg);

send(sockfd,&filedata,sizeof(struct message),0);

}

else

{

printf("读取文件失败,文件传输中止\n");

break;

}

} while (filedata.size > 0);

close(savefilefd);

savefilefd = -1 ;

}

void handlerecvmsg(int *sockfd)

{

int connfd = *sockfd;

int nread;

char buf[1024];

char str[1024];

struct message recvmsg;

time_t timep;

struct msq msg;

if(( fd = open("chatlog.txt",O_RDWR|O_CREAT|O_APPEND)) < 0)

{

printf("打开聊天记录文件失败!");

exit(1);

}

// printf("%d\n",fd);

if((qid = msgget(2222,IPC_CREAT|0666)) == -1)

{

printf("创建消息队列失败\n");

exit(1);

}

msg.msg_type = getpid();

strcpy(msg.msg_text,"OK");

while(1)

{

nread = recv(connfd,&recvmsg,sizeof(struct

message),0);

if(nread == 0)

{

printf("与服务器断开了连接\n");

close(fd);

close(connfd);

exit(0);

}

else if (strcmp(recvmsg.flag,"all") == 0)

{

time (&timep);

sprintf(str,"%s%s发给所有人:%s\n\n",ctime(&timep),https://www.360docs.net/doc/bd2144528.html,,recvmsg.ms g);

}

else if (strcmp(recvmsg.flag,"sermsg") == 0)

{

time (&timep);

printf("%s服务器发给所有人:%s\n\n",ctime(&timep),recvmsg.msg);

continue;

}

else if (strcmp(recvmsg.flag,"view") == 0)

{

time (&timep);

printf("%s当前在线客户端:\n%s\n\n",ctime(&timep),recvmsg.msg);

continue;

}

else if (strcmp(recvmsg.flag,"trans") == 0)

{

pthread_t pid;

if (strcmp(recvmsg.msg,"agree") == 0)

{

strcpy(filefromname,https://www.360docs.net/doc/bd2144528.html,);

//创建线程发送文件

pthread_create(&pid,NULL,(void *)handlesendfile,NULL);

}

else if(strcmp(recvmsg.msg,"disagree") == 0)

{

printf("对方拒绝接收文件\n");

close(savefilefd);

savefilefd = -1;

}

else if(strcmp(recvmsg.msg,"noexist") == 0)

{

printf("该客户端不存在\n");

close(savefilefd);

savefilefd = -1;

}

else

{

strcpy(filefromname,https://www.360docs.net/doc/bd2144528.html,);

printf("%s向你请求传名为%s文件,是否同意接受?[agree(同意)|disagree(不同意)]\n",https://www.360docs.net/doc/bd2144528.html,,recvmsg.msg);

savefilefd = 0;

}

continue;

}

else if(strcmp(recvmsg.flag,"transf") == 0)

{

int n;

if(strcmp(recvmsg.msg,"end$") == 0)

{

printf("文件传输结束\n");

close(savefilefd);

savefilefd = -1;

continue;

}

else

{

n=write(savefilefd,recvmsg.msg,recvmsg.size);

// printf("recvmsg.msg

= %s\n",recvmsg.msg);

while(n < recvmsg.size && n > 0)

{

lseek(savefilefd,n,SEEK_CUR);

n=write(savefilefd,recvmsg.msg,recvmsg.size);

}

}

continue;

}

else

{

time (&timep);

sprintf(str,"%s%s发来的私聊消息:%s\n\n",ctime(&timep),https://www.360docs.net/doc/bd2144528.html,,recvmsg.ms g);

}

write(fd,str,strlen(str));

msgsnd(qid,&msg,sizeof(struct msq),0);

}

}

int main(int argc,char *argv[])

{

struct sockaddr_in server_addr;

int port;

int do_number;

struct message a;

char str[MAXLEN];

char buf[MAXLEN];

pthread_t pid;

if(argc != 3)

{

printf("请输入服务器IP和端口\n");

exit(1);

}

port = atoi(argv[2]);

if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)

{

printf("创建socket失败\n");

exit(1);

}

signal(SIGINT,handleQuit);

printf("----------------------------------\n");

printf("|

|\n");

printf("| input a number to work |\n");

printf("|\t1.login\t\t\t |\n");

printf("|\t2.register\t\t |\n");

printf("|\t3.exit\t\t\t |\n");

printf("|

|\n");

printf("----------------------------------\n");

scanf("%d",&do_number);

gets(str);

while(do_number != 1 && do_number != 2 && do_number != 3)

{

printf("你输入的不是上面的选项,请重新输入:\n");

scanf("%d",&do_number);

gets(str);

}

if(do_number==3)

{

close(sockfd);

printf("程序已退出!\n");

exit(0);

}

bzero(&server_addr,sizeof(struct sockaddr_in));

server_addr.sin_family = AF_INET;

server_addr.sin_addr.s_addr = inet_addr(argv[1]);

server_addr.sin_port = htons(port);

if(connect(sockfd,(struct sockaddr *)&server_addr,sizeof(struct sockaddr)) == -1) {

printf("与服务器无响应,请隔一段时间再连接\n");

exit(2);

}

if(do_number ==1)

{

int n = 3;

while(n)

{

printf("请输入你的用户名:\n");

scanf("%s",https://www.360docs.net/doc/bd2144528.html,);

printf("请输入密码:\n");

scanf("%s",a.msg);

strcpy(a.flag,"login");

//a.flag[3] = '\0';

send(sockfd,&a,sizeof(a),0);

printf("正在等待服务器应答...\n");

recv(sockfd,buf,MAXLEN,0);

printf("接到服务器发来的信息:%s\n",buf);

if(strcmp(buf,"登录成功!") == 0)

{

//int i,j,k;

pthread_create(&pid,NULL,(void *)handlerecvmsg,(void *)&sockfd);

gets(str);

strcpy(a.flag,"all");

while(1)

{

memset(a.msg,0,strlen(a.msg));

memset(str,0,strlen(str));

gets(str);

strcpy(buf,a.flag);

cutStr(str,a.flag,15,a.msg,MAXLEN,'$');

printf("标志信息为:%s\n",a.flag);

if(strcmp(a.flag,"view") == 0)

{

send(sockfd,&a,sizeof(a),0);

strcpy(a.flag,buf);

continue;

}

else if ((strcmp(a.flag,"trans") == 0) && (savefilefd <=0))

{

//

printf("f=%s,a=%s,s=%d",a.flag,a.msg,savefilefd) ;

if ((strcmp(a.msg,"agree") == 0) && (savefilefd == 0))

{

char savefilename[20];

//char savefileallname[22];

printf("请输入保存的文件名,文件将保存在当前目录下!\n");

do

{

gets(savefilename);

savefilefd = open(savefilename,O_RDWR|O_CREAT|O_EXCL,06 66);

if(savefilefd

== -1)

{

printf("文件名可能存在请重新命名.\n");

}

}while(savefilefd

== -1);

if(savefilefd < 0)

{

printf("创建文件失败!\n");

savefilefd = -1;

}

else

{

strcpy(https://www.360docs.net/doc/bd2144528.html,,filefromname);

send(sockfd,&a,sizeof(a),0);

//

printf("agree :%s,%s,%s\n",a.flag,https://www.360docs.net/doc/bd2144528.html,,a.msg);

}

}

else

{

memset(https://www.360docs.net/doc/bd2144528.html,,0,strlen(https://www.360docs.net/doc/bd2144528.html,));

memset(str,0,strlen(str));

cutStr(a.msg,https://www.360docs.net/doc/bd2144528.html,,10,str,MAXLEN,'$');

if (str[0] != '\0' && https://www.360docs.net/doc/bd2144528.html,[0] != '\0')

{

char transfileallname[22];

sprintf(transfileallname,"./%s",str);

savefilefd = open(str,O_RDWR,0666);

if(savefilefd < 0)

{

printf("打开文件失败!\n");

savefilefd = -1;

}

else

{

memset(a.msg,0,strlen(a.msg));

strcpy(a.msg,str);

send(sockfd,&a,sizeof(a),0);

}

}

else

{

strcpy(a.msg,"disagree");

strcpy(https://www.360docs.net/doc/bd2144528.html,,filefromname);

send(sockfd,&a,sizeof(a),0);

}

}

strcpy(a.flag,buf);

continue;

}

if (strcmp(a.flag,"trans") == 0)

{

strcpy(a.flag,buf);

}

send(sockfd,&a,sizeof(a),0);

}

}

else

{

n--;

printf("您还有%d次机会,之后将推出程序!\n",n);

}

}

close(sockfd);

exit(3);

}

//登陆

else if(do_number ==2)

{

//register

int i =1 ;

char username[10];

char password[20];

char password_t[20];

char temp[20];

printf("请输入你的用户名:\n");

scanf("%s",username);

while(i)

{

printf("请输入密码:\n");

scanf("%s",password);

printf("youpass : %s\n",password);

printf("请再次输入密码:\n");

scanf("%s",password_t);

printf("passyou:%s\n",password_t);

if(strcmp(password,

password_t) != 0)

{

printf("输入的密码不一样\n");

i = 1;

}

else

{

i = 0;

}

}

strcpy(https://www.360docs.net/doc/bd2144528.html,,username);

strcpy(a.msg,password);

strcpy(a.flag,"reg");

//a.flag[3] = '\0';

send(sockfd,&a,sizeof(a),0);

printf("正在等待服务器应答...\n");

recv(sockfd,buf,MAXLEN,0);

printf("接到服务器发来的信息:%s\n",buf);

}

close(sockfd);

return 0;

}

/******display.c******/

#include

#include

#include

#include

#include

#include

#include

#include

#include

int qid,fd;

struct msq

{

long msg_type;

char msg_text[5];

};

void handlequit(int sign_no)

{

close(fd);

if((msgctl(qid,IPC_RMID,NULL)) < 0)

{

printf("消息队列无法关闭\n");

exit(1);

}

printf("程序正常退出\n");

raise(SIGQUIT);

}

int main() {

char buf[1024];

int n;

struct msq msg;

fd = open("chatlog.txt",O_RDONL Y|O_CREAT);

signal(SIGINT,handlequit);

if(fd<0)

{

printf("打开文件失败\n");

return -1;

}

lseek(fd,0,SEEK_END);

if((qid = msgget(2222,IPC_CREAT|0666)) == -1) {

printf("创建消息队列失败\n");

close(fd);

return -1;

}

while(1)

{

if(msgrcv(qid,&msg,sizeof(msg),0,0) < 0)

{

printf("读取消息对列失败\n客户端可能已经退出本程序将一起退出\n");

close(fd);

return -1;

}

memset(buf,0,sizeof(buf));

n = read(fd,buf,1024);

write(STDOUT_FILENO,buf,n);

}

close(fd);

return 0;

}

/******linklist.c******/

#include "linklist.h"

LinkList CreateLinkList()

{

LinkList L = (LinkList)malloc(sizeof(LNode));

L->next = NULL;

return L;

}

void deletelist(LinkList L ,datatype e)

{

int i=0;

LinkList s,p;

p = L;

while ( (strcmp(p->https://www.360docs.net/doc/bd2144528.html,,https://www.360docs.net/doc/bd2144528.html,) != 0) && p->next != NULL)

{

s=p;

p = p->next;

}

if (p->next == NULL && (strcmp(p->https://www.360docs.net/doc/bd2144528.html,,https://www.360docs.net/doc/bd2144528.html,) != 0))

{

return;

}

else

{

s->next = p->next;

free(p);

}

}

void insertend(LinkList L,datatype e)

{

int i=0;

LinkList s,p;

p = L;

while(p->next != NULL)

{

p = p->next;

i++;

}

s = (LinkList)malloc(sizeof(LNode));

s->data =e;

s->next = p->next ;

p->next =s;

}

void DisplayList(LinkList L)

{

L=L->next;

int i = 1;

while (L != NULL)

{

printf("%d. %s \n",i,L->https://www.360docs.net/doc/bd2144528.html,);

L = L->next;

i++;

}

}

/*

void main()

{

LinkList L;

datatype res=0;

L=CreateLinkList();

printf("aaaaa\n");

DisplayList(L);

printf("aaaaa\n");

printf("\n");

insertend(L,500);

printf("\n");

insertend(L,300);

printf("\n");

insertend(L,200);

DisplayList(L);

printf("\n");

deletelist(L,200);

DisplayList(L);

printf("删除第2个位置的%d后",res);

printf("\n");

}*/

/******linklist.h******/

#include

#include

#include

#include

#include

#include

#include

#include

typedef struct _clientinf

{

char name[10];

struct sockaddr_in addr_in;

int decr;

pthread_t pid;

}clientinf;

typedef clientinf datatype;

typedef struct _LNode

{ datatype data;

struct _LNode * next;

}LNode,*LinkList;

extern LinkList CreateLinkList(void);

extern void deletelist(LinkList L ,datatype e);

extern void insertend(LinkList L,datatype e);

extern void DisplayList(LinkList L);

/******server.c******/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include "linklist.h"

#include "check.h"

#define MAXLEN 1024

LinkList clientlink;

void handlesignal()

{

int choose;

char name[10];

while(1)

{

printf("1.T除指定客户端,2.关闭服务器,3.显示在线客户端\n");

scanf("%d",&choose);

while(choose < 1 || choose > 3)

{

printf("请输入上面提示的选项:\n");

scanf("%d",&choose);

}

gets(name);

if(choose == 1)

{

printf("请输入你踢出去的客户端名字:\n");

gets(name);

if(strcmp(name,"") == 0) continue;

LinkList L,s;

L = clientlink;

L=L->next;

s = L;

while((strcmp(L->https://www.360docs.net/doc/bd2144528.html,,name) != 0) && L->next != NULL)

{

s = L;

L = L->next;

}

//printf("1%s\n",L->https://www.360docs.net/doc/bd2144528.html,);

if(L->next == NULL && (strcmp(L->https://www.360docs.net/doc/bd2144528.html,,name) != 0))

{

printf("该客户端不存在\n");

}

else

{

close(L->data.decr);

pthread_cancel(L->data.pid);

s->next = L->next;

free(L);

}

printf("3\n");

}

else if(choose == 2)

{

return;

}

else if(choose == 3)

{

DisplayList(clientlink);

}

}

}

void handleclient (clientinf *client)

{

clientinf clientNode = *client;

int nread;

struct message a;

LinkList transfileNode;

char buf[MAXLEN],str[MAXLEN];

while(1)

{

nread= recv(clientNode.decr,&a,sizeof(a),0);

if(nread == 0)

{

strcpy(a.flag,"sermsg");

printf("客户端%s退出\n",https://www.360docs.net/doc/bd2144528.html,);

deletelist(clientlink ,clientNode);

LinkList L;

L = clientlink;

L=L->next;

sprintf(buf,"客户端%s退出\n",https://www.360docs.net/doc/bd2144528.html,);

while(L != NULL)

{

send(L->data.decr,buf,strlen(buf)+1,0);

L = L->next;

}

return;

}

if(strcmp(a.flag,"login") == 0)

{

int i;

i = login_check(&a);

if(i == 0)

{

strcpy(buf,"登录成功!");

strcpy(https://www.360docs.net/doc/bd2144528.html,,https://www.360docs.net/doc/bd2144528.html,);

insertend(clientlink,clientNode);

send(clientNode.decr,buf,strlen(buf)+1,0);

}

else

{

strcpy(buf,"登录失败!");

send(clientNode.decr,buf,strlen(buf)+1,0);

}

continue;

}

else if(strcmp(a.flag,"reg") == 0)

{

int i;

i = reg_check(&a);

if(i == 0)

{

strcpy(buf,"注册成功!");

strcpy(https://www.360docs.net/doc/bd2144528.html,,https://www.360docs.net/doc/bd2144528.html,);

send(clientNode.decr,buf,strlen(buf)+1,0);

}

continue;

}

else if (strcmp(a.flag,"all") == 0)

{

if (strcmp(a.msg,"") != 0)

{

LinkList L;

L = clientlink;

L=L->next;

strcpy(https://www.360docs.net/doc/bd2144528.html,,https://www.360docs.net/doc/bd2144528.html,);

while(L != NULL)

{

send(L->data.decr,&a,sizeof(struct message),0);

L = L->next;

}

}

continue;

}

else if(strcmp(a.flag,"view") == 0)

{

LinkList L;

int i = 1;

L = clientlink;

L=L->next;

memset(buf,0,strlen(buf));

Linux下基于socket的文件传输程序设计课程报告

Linux高级开发 课程设计报告 课程设计题目:Linux下基于socket的文件传输程序设计 学院:________信息工程学院_____________ 专业班级:________网络工程_____________ 年级:________级_____________________ 姓名:____________________________ 学号:________201______________ 完成时间:___2015___年____12___月_____25__日 成绩:__________________________________ 指导教师:____________________________

项目分 值 优秀 (100>x≥90) 良好 (90>x≥80) 中等 (80>x≥70) 及格 (70>x≥60) 不及格 (x<60) 评 分参考标准参考标准参考标准参考标准参考标准 学习态度15 学习态度认 真,科学作风 严谨,严格保 证设计时间并 按任务书中规 定的进度开展 各项工作 学习态度比较 认真,科学作 风良好,能按 期圆满完成任 务书规定的任 务 学习态度 尚好,遵守 组织纪律, 基本保证 设计时间, 按期完成 各项工作 学习态度尚 可,能遵守组 织纪律,能按 期完成任务 学习马虎, 纪律涣散, 工作作风 不严谨,不 能保证设 计时间和 进度 技术水平 与实际能力25 设计合理、理 论分析与计算 正确,实验数 据准确,有很 强的实际动手 能力、经济分 析能力和计算 机应用能力, 文献查阅能力 强、引用合理、 调查调研非常 合理、可信 设计合理、理 论分析与计算 正确,实验数 据比较准确, 有较强的实际 动手能力、经 济分析能力和 计算机应用能 力,文献引用、 调查调研比较 合理、可信 设计合理, 理论分析 与计算基 本正确,实 验数据比 较准确,有 一定的实 际动手能 力,主要文 献引用、调 查调研比 较可信 设计基本合 理,理论分析 与计算无大 错,实验数据 无大错 设计不合 理,理论分 析与计算 有原则错 误,实验数 据不可靠, 实际动手 能力差,文 献引用、调 查调研有 较大的问 题 创新10 有重大改进或 独特见解,有 一定实用价值 有较大改进或 新颖的见解, 实用性尚可 有一定改 进或新的 见解 有一定见解观念陈旧 论文(计算 书、图纸)撰写质量50 结构严谨,逻 辑性强,层次 清晰,语言准 确,文字流畅, 完全符合规范 化要求,书写 工整或用计算 机打印成文; 图纸非常工 整、清晰 结构合理,符 合逻辑,文章 层次分明,语 言准确,文字 流畅,符合规 范化要求,书 写工整或用计 算机打印成 文;图纸工整、 清晰 结构合理, 层次较为 分明,文理 通顺,基本 达到规范 化要求,书 写比较工 整;图纸比 较工整、清 晰 结构基本合 理,逻辑基本 清楚,文字尚 通顺,勉强达 到规范化要 求;图纸比较 工整 内容空泛, 结构混乱, 文字表达 不清,错别 字较多,达 不到规范 化要求;图 纸不工整 或不清晰 指导教师评定成绩: 指导教师签名:年月日

Linux下的Socket网络编程:一个简易聊天室的实现-徐慧军

Linux下的Socket网络编程:一个简易聊天室的实现-徐慧军

高级程序设计与应用实践 报告 一个简易聊天室的实现 姓名:徐慧军 学号:2121134 专业:电子与通信工程 学院:信息科学与技术学院 任课教师:廖晓飞 2013年05月02日

Linux下的Socket网络编程: ——一个简易聊天室的实现一、socket介绍 socket接口是TCP/IP网络的API,socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序。要学Internet上的TCP/IP 网络编程,必须理解socket接口。 socket接口设计者最先是将接口放在Unix操作系统里面的。如果了解Unix 系统的输入和输出的话,就很容易了解socket了。网络的socket数据传输是一种特殊的I/O,socket也是一种文件描述符。socket也具有一个类似于打开文件的函数调用socket(),该函数返回一个整型的socket描述符,随后的连接建立、数据传输等操作都是通过该socket实现的。常用的socket类型有两种:流式socket (SOCK_STREAM)和数据报式socket(SOCK_DGRAM)。流式是一种面向连接的socket,针对于面向连接的TCP服务应用;数据报式socket是一种无连接的socket,对应于无连接的UDP服务应用。 二、Socket创建 socket函数原型为: #include #include int socket(int domain, int type, int protocol); 功能:调用成功,返回socket文件描述符;失败,返回-1,并设置errno 参数说明: domain指明所使用的协议族,通常为PF_INET,表示互联网协议族(TCP/IP 协议族; type参数指定socket的类型: SOCK_STREAM 提供有序、可靠、双向及基于连接的字节流

基于Linux下的Socket通信(操作系统课程设计)

基于Linux下的socket通信 [开发平台]:LINUX [开发语言]:JA V A [开发工具]:ECLISPE [开发人员]:阚广稳(安徽理工大学计算机学院09-2班) I.系统描述: 本系统含有一个服务器(Server.class)和多个客户端(Clinet.class),可以通过每个客户端查看和下载服务器端共享文件夹中的文件。 II.功能描述: A.查看服务器端共享文件夹列表 操作:在Linux终端下输入java Clinet listfiles。 参数说明:listfiles是固定参数。 结果:列出所有共享文件。 B.下载服务器端共享文件夹中的文件 操作:在Linux终端下输入java Clinet download filename dirpath。 参数说明:download是固定参数,filename是想要下载的文件名,dirpath是下载文件保存的路径。 结果:下载文件filename到地址dirpath。 III.功能分析以及实现: A.问题描述:如何创建可以用于多个客户端连接的服务器? 分析解决:因为JA V A语言提供了对多线程的支持,所以我们可以把服务器设计为多线程的,对于每个客户端的连接单独开一条线程与之交 互。 主要实现代码: 服务器端: ServerSocket serversocket=new ServerSocket(5678); Socket socket; While(true){ Socket=serversocket.accept(); new ServerThread(socket).start(); } Class ServerThread extends Thread{ Socket socket; Public ServerThread(Socket socket){ this.socket=socket; } }

基于linux的socket多线程通信

1、网络中进程之间如何通信? 本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类: ?消息传递(管道、FIFO、消息队列) ?同步(互斥量、条件变量、读写锁、文件和写记录 锁、信号量) ?共享内存(匿名的和具名的) ?远程过程调用(Solaris门和Sun RPC) 但这些都不是本文的主题!我们要讨论的是网络中进程之间如何通信?首要解决的问题是如何唯一标识一个进程,否则通信无从谈起!在本地可以通过进程PID来唯一标识一个进程,但是在网络中这是行不通的。其实TCP/IP协议族已经帮我们解决了这个问题,网络层的―ip地址‖可以唯一标识网络中的主机,而传输层的―协议+端口‖可以唯一标识主机中的应用程序(进程)。这样利用三元组(ip地址,协议,端口)就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互。 使用TCP/IP协议的应用程序通常采用应用编程接口:UNIX BSD的套接字(socket)和UNIX System V的TLI(已经被淘汰),来实现网络进程之间的通信。就目前而言,几乎所有的应用程序都是采用socket,而现在又是网络时代,网络中进程通信是无处不在,这就是我为什么说―一切皆socket‖。 2、什么是Socket? 上面我们已经知道网络中的进程是通过socket来通信的,那什么是socket呢?socket起源于Unix,而Unix/Linux基本哲学之一就是―一切皆文件‖,都可以用―打开open –> 读写write/read –> 关闭close‖模式来操作。我的理解就是Socket就是该模式的一个实现,socket 即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭),这些函数我们在后面进行介绍。 socket一词的起源 在组网领域的首次使用是在1970年2月12日发布的文献IETF RFC33中发现的,撰写者为Stephen Carr、Steve Crocker和Vint Cerf。根据美国计算机历史博物馆的记载,Croker写道:―命名空间的元素都可称为套接字接口。一个套接字接口构成一个连接的一端,而一个连接可完全由一对套接字接口规定。‖计算机历史博物馆补充道:―这比BSD的套接字接口定义早了大约12年。‖ 3、socket的基本操作 既然socket是―open—write/read—close‖模式的一种实现,那么socket就提供了这些操作对应的函数接口。下面以TCP为例,介绍几个基本的socket接口函数。 3.1、socket()函数 int socket(int domain, int type, int protocol); socket函数对应于普通文件的打开操作。普通文件的打开操作返回一个文件描述字,而socket()用于创建一个socket描述符(socket descriptor),它唯一标识一个socket。这个socket描述字跟文件描述字一样,后续的操作都有用到它,把它作为参数,通过它来进行一些读写操作。 正如可以给fopen的传入不同参数值,以打开不同的文件。创建socket的时候,也可以指定不同的参数创建不同的socket描述符,socket 函数的三个参数分别为:

linux下socket编程与实例

一、基本socket函数 Linux系统是通过提供套接字(socket)来进行网络编程的。网络的socket数据传输是一种特殊的I/O,socket也是一种文件描述符。socket也有一个类似于打开文件的函数:socket(),调用socket(),该函数返回一个整型的socket的描述符,随后的连接建立、数据传输等操作也都是通过该socket实现。 1、socket函数 syntax: int socket(int domain, int type, int protocol); 功能说明: 调用成功,返回socket文件描述符;失败,返回-1,并设置errno 参数说明: domain指明所使用的协议族,通常为PF_INET,表示TCP/IP协议; type参数指定socket的类型,基本上有三种:数据流套接字、数据报套接字、原始套接字 protocol通常赋值"0"。 两个网络程序之间的一个网络连接包括五种信息:通信协议、本地协议地址、本地主机端口、远端主机地址和远端协议端口。socket数据结构中包含这五种信息。 2、bind函数 syntax: int bind(int sock_fd,struct sockaddr_in *my_addr, int addrlen); 功能说明: 将套接字和指定的端口相连。成功返回0,否则,返回-1,并置errno. 参数说明: sock_fd是调用socket函数返回值, my_addr是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针; struct sockaddr_in结构类型是用来保存socket信息的: struct sockaddr_in { short int sin_family; unsigned short int sin_port; struct in_addr sin_addr; unsigned char sin_zero[8]; }; addrlen为sockaddr的长度。 3、connect函数 syntax: int connect(int sock_fd, struct sockaddr *serv_addr,int addrlen); 功能说明: 客户端发送服务请求。成功返回0,否则返回-1,并置errno。 参数说明: sock_fd 是socket函数返回的socket描述符;serv_addr是包含远端主机IP地址和端口号的指针;addrlen是结构sockaddr_in的长度。 4、listen函数

Linux下基于socket的文件传输程序设计讲解

课程设计 课程名称Linux下基于socket的文件传输程序设计学生学院信息工程学院 专业班级 学号 学生姓名 指导教师 2013 年12月27日

引言 在互联网已经基本普及的情况下,人们越来越依赖于信息网络。因为互联网的使用,我们可以大大的节省了我们的时间及成本。所以文件、信息的传输已经是人们生活中不可缺少的东西。而现在主流的应用软件都是基于WINDOWS平台上开发运行的。 Linux操作系统本身具有非常高的安全性,不易感染病毒(这是WINDOWS系统所不能比拟的),而且可移植性强,应用于大多数的服务器。所以我们应该多开发出适合人们使用的应用软件,使得Linux更加好的为广大网民使用以保障自身的安全性。 本课设主要介绍在Linux下的文件传输原理及功能,虽然不能与主流传输软件的功能相比,但是却是占用的资源比它要少

·1课设背景分析 这次课程设计的要求是在以Linux为内核的操作系统下,实现多线程文件传输系统功能模块。系统模块分为服务器和客户端两部分,客户端实现对文件的上传、下载和查看服务器默认路径下的文件列表;服务器可以对文件进行管理操作,包括创建、删除和重命名等。 多线程文件传输是一种一对多或者多对多的关系,一般是一个服务器对应着多个客户端。客户端通过socket连接服务器,服务器要为客户端创建一个单独进程(线程)监听每个客户端的请求。 创建好连接之后文件就可以通过流的形式传输。linux内核中为我们提供了两种不同形式的读写流,包括read()、write()和send()、recv()。客户机对文件的查看指令也是通过流传递给服务器,服务器根据请求类型返回不同相应流。 根据socket原理和特点绘画出链接流程图,将客户机与服务器的相互通信划分为不同的模块,每个模块负责独立的功能项。服务器输入指令管理目录下的文件,create filename是创建文件命令,rename oldname newname是删除文命令,delete filename 是删除文件命令,同时监听着客户端的请求;客户端向服务器发送上传、下载和查看请求,从而得到不同的相应,包括将文件下载到当前路径下,从当前路径下上传文件给服务器,列出服务器的文件列表。 ·2网络通信原理及socket简介 2.1网络通信原理(TCP) 国际标准化组织(ISO)在1978年提出开放系统互连参考模型(OSI:open system interconnection reference mode),该模型是设计和描述网络通信的基本框架。OSI采用分层的额结构化技术将通信网络分为7层,从低到高为物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。 TCP/IP参考模型是由美国国防部创建,且发展至今最成功的通信协议模型,与OSI模型对应,它将网络功能分为4层,包括网络接口层、网络层、传输层和应用层,每一层都有对应的协议。在传输层的主要协议是TCP协议和UDP协议。socket连接就是基于TCP协议。TCP是一种可靠地数据传输协议。 它为应用程序提供可靠的通信连接。适合于一次传输大批数据的情况。并适用于要求得到响应的应用程序并通过3次握手。 其数据包头格式为: SYN J SYN K, ACK J+1 ACK K+1

Linux_基于socket的局域网聊天软件的设计与实现

提交日期:2012-06-20 基于socket的局域网聊天软件的设计与实现1.实验目的 《Linux操作系统课程设计B》是一门在课程《Linux操作系统与程序设计B》后独立开设的实验课程。这一门实验课程的开设目的是为了通过学生独立完成一个基于Linux平台的较大型应用程序,巩固课堂上学到的Linux平台上的编程规范、技术和技巧,培养学生的编写较大型程序的能力和提高学生综合应用素质。 本课程设计实验主要围绕Linux平台上主流的基础技术展开,这些技术包括:Linux的进程、线程通信和同步技术;socket网络通信技术等,这些技术可以集中体现并应用在并发程序设计中。通过并发程序的设计与开发,培养学生底层软件开发的能力,并为将来从事UNIX/Linux平台开发、嵌入式开发等相对高端的软件开发工作打下基础。 2.软件功能及模块划分 本软件是一个linux下基于socket的聊天室程序,能让局域网内的用户通过该软件进行简单的文字通信。在此基础上增加了 1.聊天室成员之间的发送私聊信息; 2.当新的成员加入后能自动收取最近一段时间内的聊天上下文; 3.用户能够查看历史聊天记录; 4.软件界面基于Qt实现,图形化界面方便用户操作。 主要模块划分: 服务端: 数据包发送和接受模块,聊天记录数据库读写模块,数据包处理模块,聊天记录查询模块 客户端: 数据包发送和接受模块,数据包处理模块,聊天记录查询模块,用户界面与展示模块

3.设计与实现 3.1系统概述与总体结构 本系统采用CS架构,服务端采用固定的端口通信,每个客户端动态设置端口。客户端启动后向服务端告知自己所使用的端口号,以便可以双向通信,同时服务器负责为每个客户端分配一个唯一的ID(服务器的ID为1) 客户端和服务端以及客户端和客户端之间采用约定的数据格式进行通信,以便接收方可以正确的解析命令和数据。 数据包通用格式定义如下 #define MAX_UDP_SIZE 1000 struct udp_packet{ int type; int senderId; long size; char content[MAX_UDP_SIZE]; }; type:表示该数据包的类型,直接决定content字段的含义 senderId:该数据包的发送者的ID, size:整个数据包的数据长度 content:数据包的内容,其数据格式由type决定。 服务器和客户端接受到数据包后,根据type字段的值来解析content字段的数据,从而作出正确的处理和响应。 所有的数据包类型以及对应的content字段的数据结构全部定义在define.h文件中 [系统总体结构]

Linux下基于socket的文件传输程序设计

课程设计报告 课程设计题目:Linux下基于socket的文件传输程序设计 学院: 专业班级: 年级: 姓名: 学号: 完成时间:年月日 成绩: 指导教师:

课程设计指导教师评定成绩表 项目分 值 优秀 (100>x≥90) 良好 (90>x≥80) 中等 (80>x≥70) 及格 (70>x≥60) 不及格 (x<60) 评 分参考标准参考标准参考标准参考标准参考标准 学习态度15 学习态度认 真,科学作风 严谨,严格保 证设计时间并 按任务书中规 定的进度开展 各项工作 学习态度比较 认真,科学作 风良好,能按 期圆满完成任 务书规定的任 务 学习态度 尚好,遵守 组织纪律, 基本保证 设计时间, 按期完成 各项工作 学习态度尚 可,能遵守组 织纪律,能按 期完成任务 学习马虎, 纪律涣散, 工作作风 不严谨,不 能保证设 计时间和 进度 技术水平 与实际能力25 设计合理、理 论分析与计算 正确,实验数 据准确,有很 强的实际动手 能力、经济分 析能力和计算 机应用能力, 文献查阅能力 强、引用合理、 调查调研非常 合理、可信 设计合理、理 论分析与计算 正确,实验数 据比较准确, 有较强的实际 动手能力、经 济分析能力和 计算机应用能 力,文献引用、 调查调研比较 合理、可信 设计合理, 理论分析 与计算基 本正确,实 验数据比 较准确,有 一定的实 际动手能 力,主要文 献引用、调 查调研比 较可信 设计基本合 理,理论分析 与计算无大 错,实验数据 无大错 设计不合 理,理论分 析与计算 有原则错 误,实验数 据不可靠, 实际动手 能力差,文 献引用、调 查调研有 较大的问 题 创新10 有重大改进或 独特见解,有 一定实用价值 有较大改进或 新颖的见解, 实用性尚可 有一定改 进或新的 见解 有一定见解观念陈旧 论文(计算 书、图纸)撰写质量50 结构严谨,逻 辑性强,层次 清晰,语言准 确,文字流畅, 完全符合规范 化要求,书写 工整或用计算 机打印成文; 图纸非常工 整、清晰 结构合理,符 合逻辑,文章 层次分明,语 言准确,文字 流畅,符合规 范化要求,书 写工整或用计 算机打印成 文;图纸工整、 清晰 结构合理, 层次较为 分明,文理 通顺,基本 达到规范 化要求,书 写比较工 整;图纸比 较工整、清 晰 结构基本合 理,逻辑基本 清楚,文字尚 通顺,勉强达 到规范化要 求;图纸比较 工整 内容空泛, 结构混乱, 文字表达 不清,错别 字较多,达 不到规范 化要求;图 纸不工整 或不清晰 指导教师评定成绩: 指导教师签名:年月日课程设计指导教师评定成绩表

基于Linux的Socket网络编程及性能优化

福建电脑2012年第12期 基于Linux的Socket网络编程及性能优化 马丽洁 (内蒙古电子信息职业技术学院内蒙古呼和浩特010070) 【摘要】:本文主要从Socket的建立、配置、连接、数据传输和结束通信五个方面阐述了基于Linux的Socket网络编程的方法和步骤,最后又从最小化报文传输延迟、最小化系统调用负载、为Bandwidth Delay Product调节tcp窗口、动态优化GNU/linux TCP/IP协议栈四个方面进行性能优化,以使应用程序高效、稳定。 【关键词】:Linux,Socket,网络编程,性能优化 Socket的英文原义是“孔”或“插座”,通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原意那样,象一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电,有的提供110伏交流电,有的则提供有线电视节目。客户软件将插头插到不同编号的插座,就可以得到不同的服务。socket也是一种文件描述符。 1.Socket编程 1.1Socket的建立 为了建立Socket,程式能够调用Socket函数,该函数返回一个类似于文档描述符的句柄。Socket描述符是个指向内部数据结构的指针,他指向描述符表入口。调用Socket函数时,socket执行体将建立一个Socket,实际上"建立一个Socket"意味着为一个Socket数据结构分配存储空间。Socket执行体为您管理描述符表。 两个网络程式之间的一个网络连接包括五种信息:通信协议、本地协议地址、本地主机端口、远端主机地址和远端协议端口。Socket数据结构中包含这五种信息。 1.2Socket的配置 通过socket调用返回一个socket描述符后,在使用socket进行网络传输以前,必须配置该socket。面向连接的socket客户端通过调用Con-nect函数在socket数据结构中保存本地和远端信息。无连接socket的客户端和服务端连同面向连接socket的服务端通过调用bind函数来配置本地信息。 Bind函数将socket和本机上的一个端口相关联,随后您就能够在该端口监听服务请求。 使用bind函数时,能够用下面的赋值实现自动获得本机IP地址和随机获取一个没有被占用的端口号。注意在使用bind函数是需要将sin_port和sin_addr转换成为网络字节优先顺序;而sin_addr则无需转换。 1.3建立连接 面向连接的客户程式使用Connect函数来配置socket并和远端服务器建立一个TCP连接,Connect函数启动和远端主机的直接连接。只有面向连接的客户程式使用socket时才需要将此socket和远端主机相连。无连接协议从不建立直接连接。面向连接的服务器也从不启动一个连接,他只是被动的在协议端口监听客户的请求。 Listen函数使socket处于被动的监听模式,并为该socket建立一个输入数据队列,将到达的服务请求保存在此队列中,直到程式处理他们。 accept()函数让服务器接收客户的连接请求。在建立好输入队列后,服务器就调用accept函数,然后睡眠并等待客户的连接请求。 首先,当accept函数监控的socket收到连接请求时,socket执行体将建立一个新的socket,执行体将这个新socket和请求连接进程的地址联系起来,收到服务请求的初始socket仍能够继续在以前的socket上监听,同时能够在新的socket描述符上进行数据传输操作。 1.4数据传输 Send()和recv()这两个函数用于面向连接的socket上进行数据传输。 Send()函数返回实际上发送出的字节数,可能会少于您希望发送的数据。在程式中应该将send ()的返回值和欲发送的字节数进行比较。当send()返回值和len不匹配时,应该对这种情况进行处 106

Linux C的socket聊天室设计与实现

基于Linux C的socket聊天室 1 系统功能 1.1 支持群聊天。 1. 2 支持向指定用户发送悄悄话功能 。 1. 3 支持不同消息不同颜色显示。 1. 4 用户名为登录的唯一标示,所以不允许重名,客户端登录具有重名检查功能。 1. 5 支持上线下线通知。 1. 6 支持服务器发送系统消息功能。 1. 7 支持登录时检测服务器是否在线。 1. 8 支持服务器下线通知客户端,客户端强行下线。 2 硬件平台 2.1 功能 用来作为对Linux C程序所用软件以及操作系统的安装的载体, 2. 2 特点 计算机的整体配置还算不错,4G内存,500G硬盘,1G独立显卡等,使得运行一般的大游戏都不卡。 2. 3 组成 K43T系列华硕计算机一台,外加键盘一个。

3 软件平台 3.1 操作系统平台 主要有Windows7操作系统和ubuntu操作系统,电脑以安装Window7为主,ubuntu操作系统以虚拟系统的方式安装在电脑上。 3. 2 系统软件平台 主要用到的软件有:Linux的ubuntu操作系统,VMware Workstation软件,Window7下的记事本软件,wps软件和CodeBlocks C编程软件以及GCC编译器等等。 3. 3 系统设计 3.3.1模块设计 主要写了两个模块程序,一个是服务端程序,另一个是客户端程序,在服务端程序主要完成对服务的基本配置以及对客户端程序的一些初始化参数进行设计等,实现端用户聊天的功能。在客户端程序里,完成对客户信息的封装,可以供多个客户同时登陆,并能对错误信息给出对应的提示,方便用户使用。服务程序文件盒客户端程序文件分别为server.c和client.c,使用Gcc来调试运行成server和client文件,先启动server程序,配置服务端信息,然后启动客户端client程序,用户登陆,进行聊天。 3.3.2 服务端程序server.c主要代码如下: typedef struct { char name[10]; SA_IN address; } USER; //XXX :用户链表 typedef struct Hnode_list { USER data; struct Hnode_list *next; } Hlink, *plink; int memoryError(plink p); int creatUserList(plink head); int findUser(plink head, char name[10]); int delUser(plink head, char name[10]); int getAllUser(plink const head); int addUser(plink head, USER data); //XXX :用户链表 void ProcessLogin(char* command, SA_IN rec_addr); void ProcessChat(char* command);

linux基于socket下的简单聊天室

Linux操作系统与程序设计课程设计B报告书 姓名: 学号: 班级: 专业: 指导老师:郭玉华 计算机学院 时间:2013年7月5日

一、课程设计目的 本次课设主要是为了加强对Linux系统下的编程的各种知识点的整合与灵活运用,让我们更加熟悉Linux下的编程操作。重点在Linux下socket编程,了解TCP、UDP等协议的使用,并完成课设题目。 二、课程设计的实验环境 硬件:PC机两台以上 软件:LINUX系统 VIM编译器, Fedora 三、课程设计总体要求 1.在LINUX下实现网络聊天,包括公聊、一对多私聊等功能; 2.实现客户端之间经网络传输文件; 3.保存聊天记录,以备必要时查询。 系统功能 系统主要实现4大聊天室功能: 1.注册与登录系统 2.公聊 3.私聊 4.文件传输 模块调用关系 各模块间调用关系如图2-2所示:

图2-2 各模块间调用关系功能需求与系统模块的关系 实现原理 一、注册、登陆实现原理服务器端 服务器端建立好socket,等待连接,当客户端连接服务器,服务器接收连接,并接受客户端发送过来的消息,根据接收到的结构体所携带的协议来做相应的功能。服务器端启动后如图3-1所示: 图3-1 服务器端界面 1、注册:如果协议为reg,则为客户端注册,首先将发送过来的结构体,提取用户名和密码,然后需要对用户名合法性检验,验证之后如果用户名合法则将用户信息保存到文件中,合法性的规则包括用户名不能重复和不能使用all等协议作为用户名,并且用户名和密码都不能为空。如果注册成功,服务器端发送一个消息给注册的客户端,同样将消息保存在一个结构体里。如果失败,也给客户端发送一个消息如“您输入的用户名不能为all”或者“用户名XX已经存在”。注册结果如图3-2所示。 图3-2 注册新用户

基于Linux的socket编程的聊天室设计

TCP/IP实验报告基于Linux的socket编程的聊天室设计 2014/1/16

一、实验目的 基于Socket 套接口,实现聊天程序的设计与实现,增强程序编写能力,了解基于socket的程序设计方法,加深对计算机网络通信的理解。另外,通过课程设计培养自己严谨的科学态度,认真的工作作风、团队协作精神、自主设计和独力思考的能力。 二、实验原理 实验中,客户应用程序向服务器程序请求服务。服务进程一直处于休眠状态,直到一个客户向这个服务的地址提出了连接请求。在这个时刻,服务程序被"惊醒"并且为客户提供服务-对客户的请求作出适当的反应。 客户端部分: 1.手动输入服务器端IP地址和端口号进行连接 2.发送消息给服务器端并显示服务器端回传的消息 3.监控连接状态,客户离开或故障时从列表中删除相应表项,并及时更新连接 表。 服务器端部分: 1.手动建立服务器端与客户端的连接请求 2.把用户输入的信息及时发送到服务端,同时准备好接受,并显示信息。 3.在用户退出时关闭连接并保存聊天记录。 客户端-服务器端架构:

相关函数: socket()函数: int socket(int family,int type,int proto); 1) family 指定protocol family (PF_INET 对应TCP/IP). 2) type 指定服务类型(SOCK_STREAM, SOCK_DGRAM). 3) protocol 指定协议(通常0, 代表缺省值). bind()函数:

给socket 绑定一个地址. int bind( int sockfd, const struct sockaddr *myaddr, socklen_t addrlen); bind 返回值 listen()函数: accept()函数: int accept( int sockfd,struct sockaddr* cliaddr, socklen_t *addrlen); sockfd 是被动模式的TCP socket. cliaddr 指针,指向一个已分配好的空间. 返回客户地址. addrlen 是一个value-result参数 必须设置为cliaddr 的空间大小

Linux课程设计(Socket通讯)

Linux操作系统与程序设计课程设计指导书 安徽工业大学计算机学院

一、实验目的: 《Linux操作系统课程设计》是一门在课程《Linux操作系统与程序设计》后独立开设的实验课程。这一门实验课程的开设目的是为了通过学生独立完成一个基于Linux平台的较大型应用程序,巩固课堂上学到的Linux平台上的编程规范、技术和技巧,培养学生的编写较大型程序的能力和提高学生综合应用素质。 本课程设计实验主要围绕Linux平台上主流的基础技术展开,这些技术包括:Linux的进程、线程通信和同步技术;Mysql数据库访问技术;socket网络通信技术;图形界面(gnome)技术等,这些技术集中体现并应用在一个较大型程序------基于Linux的网络即时通信工具设计和开发中。我们期望通过这个较大型程序的设计与开发,培养学生从事大型软件开发的能力,加强学生作为软件开发团队的一员的协作精神和素质,并为将来毕业从事UNIX/Linux平台开发、嵌入式开发等相对高端的软件开发工作打下基础。 二、适应专业:计算机科学和技术专业、软件工程、网络工程 三、实验学时:40学时 四、实验内容及学时安排: 学生的设计和开发工作始于阅读和理解教师提供的框架程序,框架程序主要包括3个部分:Linux文本界面下的网络通信示例程序,Linux下利用C语言访问Mysql数据库的示例程序,Linux下gnome图形界面窗口示例程序。学生在理解和掌握这些示例程序中包含的技术基础之上,将这些技术融合在一个较大型程序------基于Linux的网络即时通信工具设计和开发中。要求前台基于Linux下的gnome图形环境并界面友好,后台使用Mysql数据库,网络通信利用socket 技术。实验的结果不仅应提交可以运行的二进制代码和源程序还应该包括完善的程序文档和数据等软件配置说明。

相关主题
相关文档
最新文档