基于UDP协议和GTK+用户界面的Linux Socket端到端通信程序设计 详细设计文档

基于UDP协议和GTK+用户界面的Linux Socket端到端通信程序设计

详细设计文档

一、UDP编程函数声明

1、socket()函数声明:

#include <sys/types.h>

#include <sys/socket.h>

int socket(int domain, int type, int protocol);

UDP协议参数选择domain为AF_INET,type为SOCK_DGRAM,protocol值为0。表示建立一个AF_INET族的数据包套接字,UDP使用的套接字使用SOCK_DGRAM选项。

2、通用的的套接字地址类型为struct sockaddr,在以太网中一般均采用struct scockadd_in,其定义如下:

struct sockaddr_in {

  short int sin_family; /* 地址族 */

  unsigned short int sin_port; /* 端口号 */

  struct in_addr sin_addr; /* IP地址 */

unsigned char sin_zero[8];

};

3、bind()函数声明:

#include <sys/types.h>

#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr *addr,

socklen_t addrlen);

sockfd是用socket()函数创建的套接字描述符,第二个参数addr是指向一个结构为sockaddr参数的指针,addr包含了地址端口和IP地址信息,第三个参数addrlen是addr结构的长度。用于进行对套接字进行端口和地址的绑定。

4、recvfrom()函数声明:

#include <sys/types.h>

#include <sys/socket.h>

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

sockfd是由函数socket()生成的套接字描述符。

buf是接收数据的缓冲区。

len表示缓冲区的大小。

src_addr是指向本地数据结构sockaddr_in的指针,发送数据时发送方的地址信息放在这个结构中。

addrlen是第四个参数的长度。

若发生错误,错误值保存在errno中。

5、sendto()函数声明:

#include <sys/types.h>

#include <sys/socket.h>

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

buf是发送数据的缓冲区

len是发送数据缓冲区的大小

dest_addr指向目的主机数据结构sockaddr_in的指针,接受数据的主机信息存放在这个结构中

addrlen表示第四个参数的长度

二、Linux创建线程

pthread_t recv_thread;

pthread_attr_t thread_attr;

pthread_attr_init(&thread_attr);

pthread_attr_setdetachstate(&thread_attr,PTHREAD_CREATE_DETACHED);

pthread_create(&recv_thread,&thread_attr,recv_func,NULL);

(void)pthread_attr_destroy(&thread_attr);

三、GTK+基本思想

GTK+ 虽然是用 C 语言开发,但它使用了面向对象的设计思想,并通过一些技巧实现了面向对象中的封装、继承和多态。

具体实现见代码。

开发的界面如下:

基于UDP协议和GTK+用户界面的Linux Socket端到端通信程序设计 详细设计文档

基于UDP协议和GTK+用户界面的Linux Socket端到端通信程序设计 详细设计文档

四、服务器端代码

server.h

/***********************************

* server.h *

* the header files and functions *

***********************************/

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <stdio.h>

#include <errno.h>

#include <stdlib.h>

#include <string.h>

#include <semaphore.h>

#include <unistd.h>

#include <pthread.h>

#include <arpa/inet.h>

#define bool _Bool

#define true 1

#define false 0

#define PORT 8888

#define MAXSIZE 1024

void *recv_func(void *arg);

int build_socket();

void send_text(void);

void send_func(const char *);

void show_remote_text(char rcvd_mess[]);

void show_err(char *err);

void clean_send_text(void);

void startup(void);

//////////////////////////////////

se_sock.c

/************************************************

* se_sock.c *

* function: *

* create a socket *

* create a new thread,for receive function *

* send message *

************************************************/

#include "server.h"

socklen_t len;

bool from_host;//表示客户端是否已经向本服务器发送来信息

int sockfd;

struct sockaddr_in saddr,caddr;//saddr表示本地服务器地址信息,caddr用于保存向本服务器发送信息的主机地址信息

int build_socket()

{

int res;

pthread_t recv_thread;

pthread_attr_t thread_attr;

len=sizeof(caddr);

/* Set status of thread */

res=pthread_attr_init(&thread_attr);

if(res!=0)

{

show_err("Setting detached attribute failed");

exit(EXIT_FAILURE);

}

/* Create a socket */

if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0)

{

show_err("Socket Error");

exit(1);

}

bzero(&saddr,sizeof(struct sockaddr));

saddr.sin_family=AF_INET;

saddr.sin_addr.s_addr=htonl(INADDR_ANY);

saddr.sin_port=htons(PORT);

if(bind(sockfd,(struct sockaddr *)&saddr,sizeof(struct sockaddr_in))==-1)

{

show_err("Bind Error");

exit(1);

}

/* Set the status of thread,don't wait for return of the subthread */

res=pthread_attr_setdetachstate(&thread_attr,PTHREAD_CREATE_DETACHED);

if(res!=0)

{

show_err("Setting detached attribute failed");

exit(EXIT_FAILURE);

}

/* Create a sub thread,call recv_func() */

res=pthread_create(&recv_thread,&thread_attr,recv_func,NULL);

if(res!=0)

{

show_err("Thread create error");

exit(EXIT_FAILURE);

}

/* Callback the attribute of thread */

(void)pthread_attr_destroy(&thread_attr);

}

/* Receive function */

void *recv_func(void *arg)

{

char recv_text[MAXSIZE];

while(1)

{ /* To Receive message from client and get the address infomation */

if(recvfrom(sockfd,recv_text,sizeof(recv_text),0,(struct sockaddr*)&caddr,&len)<0)

{

show_err("server recv error");

exit(1);

}

if( from_host==false ) from_host=true;

show_remote_text(recv_text);

}

}

/* Send function,send message to client */

void send_func(const char * send_text)

{

/* If there is no text,continue */

if(strlen(send_text)==1)

return;

if( !from_host ) show_err("Unknown the client's address infomation/nPlease wait the client to connect you first !/n");

/* Send message */

if(from_host&&sendto(sockfd,send_text,MAXSIZE,0,(struct sockaddr*)&caddr,len)<0)

{

show_err("S send error");

exit(1);

}

}

//////////////////////////////////////////////////

server.c

/*************************************************

* server.c *

* create the server window *

* send message to client *

*************************************************/

#include "server.h"

#include<gtk/gtk.h>

bool socket_start;

GtkTextBuffer *show_buffer,*input_buffer;

void quit_win(GtkWidget *,gpointer);

int main(int argc,char **argv)

{

GtkWidget *window;

GtkWidget *show_text,*input_text;

GtkWidget *send_button,*quit_button,*cls_button,*start_button;

GtkWidget *hbox,*vbox;

GtkWidget *scrolled1,*scrolled2;

GtkWidget *space_label;

gtk_init(&argc,&argv);

window=gtk_window_new(GTK_WINDOW_TOPLEVEL);

gtk_window_set_title(GTK_WINDOW(window),"Server");

gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);

gtk_window_set_default_size(GTK_WINDOW(window),430,320);

/* "quit" button */

g_signal_connect(GTK_OBJECT(window),"destroy",GTK_SIGNAL_FUNC(quit_win),NULL);

space_label=gtk_label_new(" ");

/* set button */

send_button=gtk_button_new_with_label("Send");

quit_button=gtk_button_new_with_label("Close");

cls_button=gtk_button_new_with_label("Clear");

start_button=gtk_button_new_with_label("Startup");

/* set textbox */

show_text=gtk_text_view_new();

input_text=gtk_text_view_new();

/* get the buffer of textbox */

show_buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(show_text));

input_buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(input_text));

/* set textbox to diseditable */

gtk_text_view_set_editable(GTK_TEXT_VIEW(show_text),FALSE);

/* scroll window */

scrolled1=gtk_scrolled_window_new(NULL,NULL);

scrolled2=gtk_scrolled_window_new(NULL,NULL);

/* create a textbox */

gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled1),show_text);

gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled2),input_text);

//gtk_container_add(GTK_CONTAINER(scrolled1), show_text);

//gtk_container_add(GTK_CONTAINER(scrolled2), input_text);

/* setting of window */

gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled1),GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);

gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled2),GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);

hbox=gtk_hbox_new(FALSE,2);

vbox=gtk_vbox_new(FALSE,2);

/* click quit to call quit_win*/

g_signal_connect(GTK_OBJECT(quit_button),"clicked",GTK_SIGNAL_FUNC(quit_win),NULL);

/* click to clear input screen*/

g_signal_connect(GTK_OBJECT(cls_button),"clicked",GTK_SIGNAL_FUNC(clean_send_text),NULL);

/* click Start to build socket*/

g_signal_connect(GTK_OBJECT(start_button),"clicked",GTK_SIGNAL_FUNC(startup),NULL);

/* create window */

gtk_box_pack_start(GTK_BOX(hbox),start_button,FALSE,FALSE,2);

gtk_box_pack_start(GTK_BOX(hbox),space_label,TRUE,TRUE,2);

gtk_box_pack_start(GTK_BOX(hbox),send_button,FALSE,FALSE,2);

gtk_box_pack_start(GTK_BOX(hbox),cls_button,FALSE,FALSE,2);

gtk_box_pack_start(GTK_BOX(hbox),quit_button,FALSE,FALSE,2);

gtk_box_pack_start(GTK_BOX(vbox),scrolled1,TRUE,TRUE,2);

gtk_box_pack_start(GTK_BOX(vbox),scrolled2,FALSE,FALSE,2);

gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,2);

gtk_container_add(GTK_CONTAINER(window),vbox);

/* click send button ,then call send_text*/

gtk_signal_connect(GTK_OBJECT(send_button),"clicked",GTK_SIGNAL_FUNC(send_text),NULL);

gtk_widget_show_all(window);

gtk_main();

return 0;

}

/* show the input text */

void show_local_text(const gchar* text)

{

GtkTextIter start,end;

gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(show_buffer),&start,&end);/*获得缓冲区开始和结束位置的Iter*/

gtk_text_buffer_insert(GTK_TEXT_BUFFER(show_buffer),&end,"Me:/n",4);/*插入文本到缓冲区*/

gtk_text_buffer_insert(GTK_TEXT_BUFFER(show_buffer),&end,text,strlen(text));/*插入文本到缓冲区*/

gtk_text_buffer_insert(GTK_TEXT_BUFFER(show_buffer),&end,"/n",1);/*插入文本到缓冲区*/

}

/* clean the input text */

void clean_send_text()

{

GtkTextIter start,end;

gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(input_buffer),&start,&end);/*获得缓冲区开始和结束位置的Iter*/

gtk_text_buffer_delete(GTK_TEXT_BUFFER(input_buffer),&start,&end);/*插入到缓冲区*/

}

/* get the input text,and send it */

void send_text()

{

GtkTextIter start,end;

gchar *text;

/* Socket creating has succeed ,so send message */

text=(gchar *)malloc(MAXSIZE);

if(text==NULL)

{

printf("Malloc error!/n");

exit(1);

}

/* get text */

gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(input_buffer),&start,&end);

text=gtk_text_buffer_get_text(GTK_TEXT_BUFFER(input_buffer),&start,&end,FALSE);

/* If there is no input,do nothing but return */

if(strcmp(text,"")!=0)

{

send_func(text);

clean_send_text();

show_local_text(text);

}

else

show_err("The message can not be empty .../n");

free(text);

}

void startup(void)

{

if( !socket_start )

{

build_socket();

socket_start=true;

return;

}

show_err("The server has been started !/n");

}

/* show errors such as "no input","haven't create sockt" etc. */

void show_err(char *err)

{

GtkTextIter start,end;

gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(show_buffer),&start,&end);/*获得缓冲区开始和结束位置的Iter*/

gtk_text_buffer_insert(GTK_TEXT_BUFFER(show_buffer),&end,err,strlen(err));

}

/* show the received message */

void show_remote_text(char rcvd_mess[])

{

GtkTextIter start,end;

gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(show_buffer),&start,&end);/*获得缓冲区开始和结束位置的Iter*/

gtk_text_buffer_insert(GTK_TEXT_BUFFER(show_buffer),&end,"Client:/n",8);/*插入文本到缓冲区*/

gtk_text_buffer_insert(GTK_TEXT_BUFFER(show_buffer),&end,rcvd_mess,strlen(rcvd_mess));/*插入文本到缓冲区*/

gtk_text_buffer_insert(GTK_TEXT_BUFFER(show_buffer),&end,"/n",1);/*插入换行到缓冲区*/

}

/* quit */

void quit_win(GtkWidget *window,gpointer data)

{

gtk_main_quit();

}

//////////////////////////////////

///////////////////////////////////////

客户端代码

client.h

/***********************************

* client.h *

* the header files and functions *

***********************************/

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <errno.h>

#include <unistd.h>

#include <pthread.h>

#define PORT 8888

#define MAXSIZE 1024

int build_socket(const char *);

void send_text(void);

void send_func(const char *);

void *recv_func(void *);

void show_remote_text(char rcvd_mess[]);

void clean_send_text(void);

void show_err(char *err);

////////////////////////////

cl_sock.c

/************************************************

* cl_sock.c *

* function: *

* create a socket *

* create a new thread,for receive function *

* send message *

************************************************/

#include "client.h"

int sockfd;

struct sockaddr_in saddr;

int build_socket(const char *serv_ip)

{

int res;

pthread_t recv_thread;

pthread_attr_t thread_attr;

/* set status of thread */

res=pthread_attr_init(&thread_attr);

if(res!=0)

{

perror("Setting detached attribute failed");

exit(EXIT_FAILURE);

}

sockfd=socket(AF_INET,SOCK_DGRAM,0); /* create a socket */

if(sockfd==-1)

{

perror("Socket Error");

exit(1);

}

bzero(&saddr,sizeof(saddr));

saddr.sin_family=AF_INET;

saddr.sin_port=htons(PORT);

res=inet_pton(AF_INET,serv_ip,&saddr.sin_addr);

if(res==0){ /* the serv_ip is invalid */

return 1;

}

else if(res==-1){

return -1;

}

/* set the stats of thread:means do not wait for the return value of subthread */

res=pthread_attr_setdetachstate(&thread_attr,PTHREAD_CREATE_DETACHED);

if(res!=0)

{

perror("Setting detached attribute failed");

exit(EXIT_FAILURE);

}

/* Create a thread,to process the receive function. */

res=pthread_create(&recv_thread,&thread_attr,&recv_func,NULL);

if(res!=0)

{

perror("Thread create error");

exit(EXIT_FAILURE);

}

/* callback the attribute */

(void)pthread_attr_destroy(&thread_attr);

return 0;

}

/* send function */

void send_func(const char *text)

{

int n;

socklen_t len=sizeof(saddr);

n=sendto(sockfd,text,MAXSIZE,0,(const struct sockaddr*)&saddr,len);

if(n<0)

{

perror("S send error");

exit(1);

}

}

/* a new thread,to receive message */

void *recv_func(void *arg)

{

char rcvd_mess[MAXSIZE];

while(1)

{

bzero(rcvd_mess,MAXSIZE);

if(recvfrom(sockfd,rcvd_mess,MAXSIZE,0,NULL,NULL)<0) /*阻塞直到收到客户端发的消息*/

{

perror("server recv error");

exit(1);

}

show_remote_text(rcvd_mess);

}

}

//////////////////////////////////////////

client.c

/*********************************

* Client.c *

* Function: *

* create the chat window *

*********************************/

#include "client.h"

#include <gtk/gtk.h>

int issucceed=-1;

GtkTextBuffer *show_buffer,*input_buffer;

void get_ip(GtkWidget *,gpointer);

void quit_win(GtkWidget *,gpointer);

int main(int argc,char **argv)

{

GtkWidget *window;

GtkWidget *show_text,*input_text,*ip_text;

GtkWidget *ip_label,*space_label;

GtkWidget *link_button,*send_button,*quit_button,*cls_button;

GtkWidget *hbox,*vbox;

GtkWidget *scrolled1,*scrolled2;

gtk_init(&argc,&argv);

window=gtk_window_new(GTK_WINDOW_TOPLEVEL);

gtk_window_set_title(GTK_WINDOW(window),"Client");

gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);

gtk_window_set_default_size(GTK_WINDOW(window),430,320);

/* "quit" button */

g_signal_connect(GTK_OBJECT(window),"destroy",GTK_SIGNAL_FUNC(quit_win),NULL);

ip_label=gtk_label_new("IP:");

space_label=gtk_label_new(" ");

/* set button */

link_button=gtk_button_new_with_label("Connect");

send_button=gtk_button_new_with_label("Send");

quit_button=gtk_button_new_with_label("Close");

cls_button=gtk_button_new_with_label("Clear");

/* set textbox */

ip_text=gtk_entry_new();

show_text=gtk_text_view_new();

input_text=gtk_text_view_new();

/* set length of IP box */

gtk_entry_set_max_length(GTK_ENTRY(ip_text),15);

/* get the buffer of textbox */

show_buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(show_text));

input_buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(input_text));

/* set textbox to diseditable */

gtk_text_view_set_editable(GTK_TEXT_VIEW(show_text),FALSE);

/* scroll window */

scrolled1=gtk_scrolled_window_new(NULL,NULL);

scrolled2=gtk_scrolled_window_new(NULL,NULL);

/* create a textbox */

gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled1),show_text);

gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled2),input_text);

/* setting of window */

gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled1),GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);

gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled2),GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);

hbox=gtk_hbox_new(FALSE,2);

vbox=gtk_vbox_new(FALSE,2);

/* click quit to call quit_win*/

g_signal_connect(GTK_OBJECT(quit_button),"clicked",GTK_SIGNAL_FUNC(quit_win),NULL);

/* click "connect" to call get_ip */

g_signal_connect(GTK_OBJECT(link_button),"clicked",GTK_SIGNAL_FUNC(get_ip),ip_text);

/* click to clear input screen*/

g_signal_connect(GTK_OBJECT(cls_button),"clicked",GTK_SIGNAL_FUNC(clean_send_text),NULL);

/* create window */

gtk_box_pack_start(GTK_BOX(hbox),ip_label,FALSE,FALSE,2);

gtk_box_pack_start(GTK_BOX(hbox),ip_text,FALSE,FALSE,2);

gtk_box_pack_start(GTK_BOX(hbox),link_button,FALSE,FALSE,2);

gtk_box_pack_start(GTK_BOX(hbox),space_label,TRUE,TRUE,2);

gtk_box_pack_start(GTK_BOX(hbox),send_button,FALSE,FALSE,2);

gtk_box_pack_start(GTK_BOX(hbox),cls_button,FALSE,FALSE,2);

gtk_box_pack_start(GTK_BOX(hbox),quit_button,FALSE,FALSE,2);

gtk_box_pack_start(GTK_BOX(vbox),scrolled1,TRUE,TRUE,2);

gtk_box_pack_start(GTK_BOX(vbox),scrolled2,FALSE,FALSE,2);

gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,2);

gtk_container_add(GTK_CONTAINER(window),vbox);

/* click send button ,then call send_text*/

gtk_signal_connect(GTK_OBJECT(send_button),"clicked",GTK_SIGNAL_FUNC(send_text),NULL);

gtk_widget_show_all(window);

gtk_main();

return 0;

}

/* show the input text */

void show_local_text(const gchar* text)

{

GtkTextIter start,end;

gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(show_buffer),&start,&end);/*获得缓冲区开始和结束位置的Iter*/

gtk_text_buffer_insert(GTK_TEXT_BUFFER(show_buffer),&end,"Me:/n",4);/*插入文本到缓冲区*/

gtk_text_buffer_insert(GTK_TEXT_BUFFER(show_buffer),&end,text,strlen(text));/*插入文本到缓冲区*/

gtk_text_buffer_insert(GTK_TEXT_BUFFER(show_buffer),&end,"/n",1);/*插入文本到缓冲区*/

}

/* clean the input text */

void clean_send_text()

{

GtkTextIter start,end;

gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(input_buffer),&start,&end);/*获得缓冲区开始和结束位置的Iter*/

gtk_text_buffer_delete(GTK_TEXT_BUFFER(input_buffer),&start,&end);/*插入到缓冲区*/

}

/* get the input text,and send it */

void send_text()

{

GtkTextIter start,end;

gchar *text;

if(issucceed==-1){ /* Haven't create a socket */

show_err("Not connected.../n");

}

else

{ /* Socket creating has succeed ,so send message */

text=(gchar *)malloc(MAXSIZE);

if(text==NULL)

{

printf("Malloc error!/n");

exit(1);

}

/* get text */

gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(input_buffer),&start,&end);

text=gtk_text_buffer_get_text(GTK_TEXT_BUFFER(input_buffer),&start,&end,FALSE);

/* If there is no input,do nothing but return */

if(strcmp(text,"")!=0)

{

send_func(text);

clean_send_text();

show_local_text(text);

}

else

show_err("The message can not be empty.../n");

free(text);

}

}

/* show errors such as "no input","haven't create sockt" etc. */

void show_err(char *err)

{

GtkTextIter start,end;

gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(show_buffer),&start,&end);/*获得缓冲区开始和结束位置的Iter*/

gtk_text_buffer_insert(GTK_TEXT_BUFFER(show_buffer),&end,err,strlen(err));

}

/* get IP address and create socket */

void get_ip(GtkWidget *button,gpointer ip_text)

{

gchar *serv_ip;

int res;

serv_ip=(gchar *)gtk_entry_get_text(GTK_ENTRY((GtkWidget *)ip_text));

res=build_socket(serv_ip);

if(res==1)

show_err("IP Address is Invalid.../n");

else if(res==-1)

show_err("Connect Failure... /n");/*插入文本到缓冲区*/

else{

show_err("Connect Successful... /n");

issucceed=0;

}

}

/* show the received message */

void show_remote_text(char rcvd_mess[])

{

GtkTextIter start,end;

gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(show_buffer),&start,&end);/*获得缓冲区开始和结束位置的Iter*/

gtk_text_buffer_insert(GTK_TEXT_BUFFER(show_buffer),&end,"Server:/n",8);/*插入文本到缓冲区*/

gtk_text_buffer_insert(GTK_TEXT_BUFFER(show_buffer),&end,rcvd_mess,strlen(rcvd_mess));/*插入文本到缓冲区*/

gtk_text_buffer_insert(GTK_TEXT_BUFFER(show_buffer),&end,"/n",1);/*插入换行到缓冲区*/

}

/* quit */

void quit_win(GtkWidget *window,gpointer data)

{

gtk_main_quit();

}

/////////////////////////////

Makefile

OBJ=client.o cl_sock.o

OBJ1=server.o se_sock.o

server:server.o se_sock.o server.h

gcc -Wall $(OBJ1) -o server `pkg-config gtk+-2.0 --libs` -l pthread

server.o:server.c server.h

gcc -Wall -c $< `pkg-config gtk+-2.0 --cflags`

server_sock.o:se_sock.c server.h

gcc -Wall -c $<

client:client.o cl_sock.o client.h

gcc -Wall $(OBJ) -o client `pkg-config gtk+-2.0 --libs` -l pthread

client.o:client.c client.h

gcc -Wall -c $< `pkg-config gtk+-2.0 --cflags`

client_sock.o:cl_sock.c client.h

gcc -Wall -c $<

clean:

rm *.o

你可能感兴趣的:(socket)