免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6566 | 回复: 6
打印 上一主题 下一主题

帮忙补全socket服务器和客户端交互通信 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-12-15 12:55 |只看该作者 |倒序浏览
我在Redhat9上写了一个sokcet通信的程序,但不会写交互通信,就是send()和recv()同时在服务器和客户端的代码,我想做到服务器和客户端建立连接后自由的会话,就像聊天一样。请会的DX补全代码。大家一起学习进步!服务器端使用了多线程技术,但有些问题。
gcc -g -o socket_server socket_server.c -lpthread
gcc -g -o socket_client socket_client.c

//服务器端代码,socket_server.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <pthread.h>
#define SERVPORT 3333 /*服务器监听端口号 */
#define BACKLOG 10 /* 最大同时连接请求数 */
#define MAXDATASIZE 100 /*每次最大数据传输量 */

static void *communicate(void *arg);
pthread_mutex_t mutex;/* 互斥体 */
char buf[MAXDATASIZE];/* 接受缓冲 */
char msg[MAXDATASIZE];/* 发送缓冲 */

main()
{
        int sockfd, client_fd; /*sock_fd:监听socket; client_fd:数据传输socket */
        pthread_t tid[BACKLOG];/* 线程数组 */
        int pthindex = 0;/* 线程索引 */
        int sin_size, i;
        struct sockaddr_in my_addr; /* 本机地址信息 */
        struct sockaddr_in remote_addr; /* 客户端地址信息 */
               
        if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        {
                perror("socket创建出错!"); exit(1);
        }
        my_addr.sin_family=AF_INET;
        my_addr.sin_port=htons(SERVPORT);
        my_addr.sin_addr.s_addr = INADDR_ANY;
        bzero(&(my_addr.sin_zero),8);
        if(bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
        {
                perror("bind出错!");
                exit(1);
        }
        if(listen(sockfd, BACKLOG) == -1)
        {
                perror("listen出错!");
                exit(1);
        }
        pthread_mutex_init(&mutex, NULL);
        while(1)
        {
                sin_size = sizeof(struct sockaddr_in);
                if((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size)) == -1)
                {
                        perror("accept出错");
                        continue;
                }
                printf("received a connection from %s\n", inet_ntoa(remote_addr.sin_addr));
                 if(pthread_create(&tid[pthindex++], NULL,communicate, (void *)client_fd))
                 {
                         perror("创建线程失败!");  
                        exit(1);       
                 }
                close(client_fd);
        }
        for(i=0; i <= pthindex; i++)
        {
                if(pthread_join( tid[i],NULL ))
                {
                        perror("等待线程结束失败!");
                        exit(1);
                }
        }
}

//线程调用函数
static void *communicate(void *arg)
{
        /* 子进程代码段 */
        int recvbytes; /* 接受数据字节 */
        int client_fd = (int)arg;
        int i = 0;
        while(i++ < 10)
        {
        if(send(client_fd, "Welcome, you are connected!\n", 26, 0) == -1)
                perror("send出错!");
        //while(1)
        //{        //send message.
                //pthread_mutex_lock(&mutex);
                //printf("socket server:please input your message.\n");
                //scanf("%s", msg);
                //printf("server print:%s\n", *msg);
                 //if(send(client_fd, msg, MAXDATASIZE, 0) == -1)
                         //perror("send出错!");
                //pthread_mutex_unlock(&mutex);
        //}
        }
        close(client_fd);
        return NULL;       
}

//客户端代码,socket_client.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define SERVPORT 3333
#define MAXDATASIZE 100 /* 每次最大数据传输量 */
main(int argc, char *argv[])
{
        int sockfd, recvbytes;
        char buf[MAXDATASIZE];
        struct hostent *host;
        struct sockaddr_in serv_addr;
        char msg[MAXDATASIZE];
        char szexit[4];//用来匹配"exit"的字符串
        if(argc < 2)
        {
                fprintf(stderr,"Please enter the server's hostname!\n");
                exit(1);
        }
        if((host=gethostbyname(argv[1]))==NULL)
        {
                herror("gethostbyname出错!");
                exit(1);
        }
        if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        {
                perror("socket创建出错!");
                exit(1);
        }
        serv_addr.sin_family=AF_INET;
        serv_addr.sin_port=htons(SERVPORT);
        serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
        bzero(&(serv_addr.sin_zero),8);/* memset(&serv_addr.sin_zero,0,8); */
        if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1)
        {
                perror("connect出错!");
                exit(1);
        }
        while(1)
        {       
                //receive message.
                if((recvbytes=recv(sockfd, buf, MAXDATASIZE, 0)) ==-1)
                {
                        perror("recv出错!");
                        exit(1);
                }
                buf[recvbytes] = '\0';
                if(recvbytes > 0)
                        printf("Received: %s\n",buf);
        }
        close(sockfd);
}

[[i] 本帖最后由 willing_wlmq 于 2005-12-15 12:57 编辑 [/i]]

论坛徽章:
0
2 [报告]
发表于 2005-12-15 15:35 |只看该作者
怎么没有人响应呀,我正在改写成C++,用CSocket封装一下。没有时间改,也给点评论嘛。

论坛徽章:
0
3 [报告]
发表于 2005-12-15 15:39 |只看该作者
我怎么简单的我比较喜欢用堵塞做

论坛徽章:
0
4 [报告]
发表于 2005-12-15 15:41 |只看该作者
看看select()函数会给你带来帮助的啊.

论坛徽章:
0
5 [报告]
发表于 2005-12-15 16:01 |只看该作者
你目前所做得太基础了,离你的目标还有一些距离,慢慢来吧.
www.infoxa.com
去下载unix网络编程第一卷
然后去下载一个Boox Viewer,然后看第23章-- 线程 第27章 ---客户服务器程序设计方法.

如果要用c++实现的话,就不需要考虑这些东西了,参考一下commoncppwww.gnu.org/software/commoncpp/,你所需要的大部分东西已经实现好了.

不过我的看法是,如果你是学习的话,还是尽可能用c实现,用c会有一种一切尽在掌握之中的感觉.

论坛徽章:
0
6 [报告]
发表于 2005-12-15 16:23 |只看该作者
感谢版主renstone921的建议,学习还是要踏实点,一步一个脚印呀。我会好好看看《unix网络编程第一卷》。

论坛徽章:
0
7 [报告]
发表于 2007-11-18 19:27 |只看该作者
good!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP