您的位置:首页 > 理论基础 > 计算机网络

网络编程练习------简单双机通讯

2016-03-28 22:48 387 查看
环境:

服务器端:Redhat 6.4 server 64bit

客户端:    Ubuntu 14.04 64bit

客户端:

1.    根据传入的参数建立socket 并与服务器建立连接。

2.    连接成功后,开两个线程,一个用于接收来自服务器端的消息;另一个用于读取用户输入,再把输入内容发送到服务器。

3.    当接收到服务器端断开消息后,退出程序。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

/*客户端接收线程*/
void *recvsocket(void *arg)
{
int st =*(int *)arg;
char buf[1024];
int rc = 0;

while(1)
{
memset(buf, 0, sizeof(buf));
rc = recv(st, buf, sizeof(buf), 0);
if(rc <= 0)
{
exit(0);
}
printf("%s", buf);
}
return NULL;
}

/*客户端发送线程*/
void *sendsocket(void *arg)
{
int st = *(int *)arg;
char buf[1024];
int rc =0;

while(1)
{
memset(buf, 0, sizeof(buf));
read(STDIN_FILENO, buf, sizeof(buf));
rc = send(st, buf, strlen(buf), 0);
if(rc <= 0)
{
break;
}
}
return NULL;
}

int main(int arg, char **args)
{
if(arg < 3)
{
printf("usage: client ipaddress port\n");
return -1;
}

int port = atoi(args[2]);

//创建socket
int st = socket(AF_INET, SOCK_STREAM, 0);
if(st == -1)
{
perror("create socket error:");
return -2;
}

//定义一个IP地址结构
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(args[1]);

//调用connect连接指定address的服务器
if(connect(st, (struct sockaddr *)&addr, sizeof(addr)) == -1)
{
perror("connect error:");
return -3;
}

pthread_t thrd1, thrd2;
pthread_create(&thrd1, NULL, recvsocket, &st);
pthread_create(&thrd2, NULL, sendsocket, &st);
pthread_join(thrd1, NULL);
pthread_join(thrd2, NULL);

return 0;

}


服务器端:

1.    根据传入的参数建立socket,并等待客户端连接到来。

2.    当收到一个客户端请求时,置连接状态为1,以表示不再接收其他客户端连接请求(为了避免聊天时,不知道发给谁),开两个线程,一个用于接收客户端的消息,另一个发送消息。

3.    当服务器接收到客户端断开连接消息,把连接状态置为0,服务器可以再接收其他客户端的连接。为了避免同时改变连接状态的值,在改变连接状态的前加锁。并把发送消息线程取消。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

/*结构体:用于传送消息到线程中*/
struct ps_info
{
int st;
pthread_t *p;
};

/*标志:是否已经有客户端连接*/
int status = 0;
/*锁*/
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

/*服务器接收线程*/
void *recvsocket(void *arg)
{
struct ps_info ps1 = *(struct ps_info *)arg;
int st =ps1.st;
char buf[1024];
int rc = 0;

while(1)
{
memset(buf, 0, sizeof(buf));
rc = recv(st, buf, sizeof(buf), 0);
if(rc <= 0)
{
break;
}
printf("%s", buf);
}
pthread_mutex_lock(&mutex);
status = 0;						//把连接状态置0
pthread_mutex_unlock(&mutex);
pthread_cancel(*ps1.p);			//把发送线程取消
return NULL;
}

/*服务器发送线程*/
void *sendsocket(void *arg)
{
int st = *(int *)arg;
char buf[1024];
int rc =0;

while(1)
{
memset(buf, 0, sizeof(buf));
read(STDIN_FILENO, buf, sizeof(buf));
rc = send(st, buf, strlen(buf), 0);
if(rc <= 0)
{
break;
}
}
return NULL;
}

int main(int arg, char **args)
{
if(arg < 3)
{
printf("usage: client ipaddress port\n");
return -1;
}

int port = atoi(args[2]);

/*创建socket*/
int st = socket(AF_INET, SOCK_STREAM, 0);
if(st == -1)
{
perror("create socket error:");
return -2;
}

//定义一个IP地址结构
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)
{
perror("bind error:");
return -2;
}

if(listen(st, 20) == -1)
{
perror("listen error:");
return -2;
}

int client_st = 0;
socklen_t len =0;
struct sockaddr_in client_addr;
pthread_t thrd1, thrd2;

while(1)
{
memset(&client_addr, 0, sizeof(client_st));
len = sizeof(client_addr);
client_st = accept(st, (struct sockaddr *)&client_addr, &len);

pthread_mutex_lock(&mutex);
status++;
pthread_mutex_unlock(&mutex);
if(status > 1)
{
close(client_st);
continue;
}

if(client_st == -1)
{
perror("accept error:");
return -3;
}

printf("accept by %s\n", inet_ntoa(client_addr.sin_addr));

struct ps_info ps1;
ps1.st = client_st;
ps1.p = &thrd1;

pthread_create(&thrd1, NULL, recvsocket, &ps1);
pthread_detach(thrd1);
pthread_create(&thrd2, NULL, sendsocket, &client_st);
pthread_detach(thrd2);
}

close(st);

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 网络编程