通用头文件:
#ifndef _UTILI_H
#define _UTILI_H
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<pthread.h>
#define LISTEN_QUEUE_SIZE 5
//#define LISTEN_PORT 8080
//#define LISTEN_IP "127.0.0.1"
#define BUFFER_MAX_SIZE 256
int startup(const char *ip, short port)
{
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd == -1)
{
perror("socket.");
exit(1);
}
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_port = htons(port);
// address.sin_addr.s_addr = INADDR_ANY;
address.sin_addr.s_addr = inet_addr(ip);
socklen_t addrlen = sizeof(struct sockaddr );
int yes = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
int ret = bind(sockfd, (struct sockaddr*)&address, addrlen);
if(ret == -1)
{
perror("bind.");
close(sockfd);
exit(1);
}
ret = listen(sockfd,LISTEN_QUEUE_SIZE);
if(ret == -1)
{
perror("listen.");
close(sockfd);
exit(1);
}
return sockfd;
}
#endif
服务器端的程序:
#include"utili.h"
void* send_msg(void *arg)
{
char sendbuf[BUFFER_MAX_SIZE];
int sockCo = *(int *)arg;
while(1)
{
printf("Ser:>");
scanf("%s", sendbuf);
if(!strcmp(sendbuf, "quit"))
break;
send(sockCo, sendbuf, strlen(sendbuf)+1,0);
}
pthread_exit(0);
}
void* recv_msg(void *arg)
{
char recvbuf[BUFFER_MAX_SIZE];
int sockCo = *(int *)arg;
while(1)
{
recv(sockCo, recvbuf, BUFFER_MAX_SIZE, 0);
if(!strcmp(recvbuf, "quit"))
break;
printf("Cli:>%s\n",recvbuf);
}
pthread_exit(0);
}
int main(int argc, char *argv[])
{
if(argc < 3)
{
printf("Usage: ./ser ip port.\n");
exit(1);
}
int sockSer = startup(argv[1],atoi(argv[2]));
struct sockaddr_in addrCli;
socklen_t addrlen = sizeof(struct sockaddr);
printf("Server is waiting to connsect with client.\n");
while(1)
{
int sockConn = accept(sockSer, (struct sockaddr*)&addrCli,&addrlen);
if(sockConn == -1)
{
printf("Accept cli fail.\n");
//close(sockSer);
//exit(1);
continue;
}
else
printf("Accept cli success.\n");
printf("Cli ip:>%s\n",inet_ntoa(addrCli.sin_addr));
printf("Cli port:>%d\n",ntohs(addrCli.sin_port));
pthread_t tid[2];
// int sockConn;
pthread_create(&tid[0], NULL, send_msg, &sockConn);
pthread_create(&tid[1], NULL, recv_msg, &sockConn);
}
close(sockSer);
return 0;
}
客户端程序:
#include"utili.h"
void* send_msg(void *arg)
{
int sockCli = *(int *)arg;
char sendbuf[BUFFER_MAX_SIZE];
while(1)
{
printf("Cli:>");
scanf("%s",sendbuf);
if(!strcmp(sendbuf,"quit"))
break;
send(sockCli, sendbuf, strlen(sendbuf)+1,0);
}
pthread_exit(0);
}
void* recv_msg(void *arg)
{
int sockCli = *(int *)arg;
char recvbuf[BUFFER_MAX_SIZE];
while(1)
{
recv(sockCli, recvbuf, BUFFER_MAX_SIZE, 0);
if(!strcmp(recvbuf, "quit"))
break;
printf("Ser:>%s\n",recvbuf);
}
pthread_exit(0);
}
int main(int argc, char* argv[])
{
if (argc < 3)
{
printf("Usage: ./cli ip port.");
}
int sockCli = socket(AF_INET,SOCK_STREAM, 0);
if(sockCli == -1)
{
perror("socket.");
exit(1);
}
struct sockaddr_in addrSer;
addrSer.sin_family = AF_INET;
addrSer.sin_port = htons(atoi(argv[2]));
addrSer.sin_addr.s_addr = inet_addr(argv[1]);
socklen_t addrlen = sizeof(struct sockaddr);
struct sockaddr_in addrCli;
addrCli.sin_family = AF_INET;
addrCli.sin_port = htons(12345);
addrCli.sin_addr.s_addr = inet_addr("127.0.0.1");
// bind(sockCli, (struct sockaddr*)&addrCli, addrlen);
int ret = connect(sockCli, (struct sockaddr*)&addrSer, addrlen);
if(ret == -1)
{
perror("Connect server fail.\n");
close(sockCli);
exit(1);
}
else
printf("Connect server success.\n");
char recvbuf[BUFFER_MAX_SIZE];
pthread_t tid[2];
pthread_create(&tid[0], NULL, send_msg, &sockCli);
pthread_create(&tid[1], NULL, recv_msg, &sockCli);
pthread_join(tid[0], NULL);
pthread_join(tid[1], NULL);
close(sockCli);
return 0;
}
利用多线程分别处理收发,达到通信中随意收发的目的。现在的问题是服务器的消息只能发送到第一个和服务器连接的客户端。后面的客户端可以发消息给服务器,但服务器的消息却是发不过来。不知道出了什么问题,这是后续要解决的一个大问题。难道是因为系统内部的竞争问题?