const int PORT = 3344;
int ssocks[QLEN] ;
void recvMsg(int fd);
void broadcastMsg(int, char *,int);
int errexit(const char *format, ...);
int passiveTCP(int port, int qlen);
int main(int argc, char *argv[])
{
pthread_t th[QLEN];
int conncount = 0;
int port = PORT;
struct sockaddr_in fsin;
unsigned int alen;
int msock;
//接收参数
switch (argc)
{
case 1:
break;
case 2:
port = atoi(argv[1]);
default:
errexit("usage:ChatServer[port]\n");
}
//获取主套接字
msock = passiveTCP(port, QLEN);
while (1)
{
alen = sizeof(fsin);
ssocks[conncount++] = accept(msock, (struct sockaddr *)&fsin, &alen);
if (ssocks[conncount - 1] < 0)
{
if (errno == EINTR)
continue;
errexit("accept: %s\n", strerror(errno));
}
printf("服务器与客户端建立链接...\n\n");
if (pthread_create(&th[conncount-1], NULL, (void *(*)(void *))recvMsg,
(void *)(long)ssocks[conncount - 1]) < 0) {
printf("线程启动失败\n");
}
}
}
/*
* 接收客户端信息并转发
*/
void recvMsg(int fd)
{
int cc;
char buf[BUFSIZ + 1];
printf("进入转发线程\n");
//显示欢迎界面
char str[BUFSIZE+1] =
"-------------------------------------------------------------\n------------------------欢迎加入聊天组-----------------------\n-------------------------------------------------------------\n\n";
str[BUFSIZE]='\0';
printf("fd: %d\n",fd);
if (write(fd, str, sizeof buf) < 0)
errexit("发送欢迎界面失败!%s\n", strerror(errno));
strcpy(str,"---有新成员加入---\n\n");
broadcastMsg(fd, str, sizeof str);
while (1)
{
memset(buf,'\0',strlen(buf));
//接收改客户端信息并转发给其他客户端
while (cc = read(fd, buf, sizeof buf))
{
if (cc < 0)
errexit("recv:%s\n", strerror(errno));
printf("%s",buf);
broadcastMsg(fd,buf,cc);
}
}
shutdown(fd,2);
}
//广播消息
void broadcastMsg(int fd, char *buf,int cc)
{
for (int i = 0; i < QLEN; i++)
{
//printf("准备转发...\n");
if (ssocks[i]!=fd && ssocks[i]!=0) {
if(write(ssocks[i], buf, cc) < 0){}
}
}
buf = "广播完成\n";
fputs(buf,stdout);
}
void *recvMsg(int fd);
int errexit(const char *format, ...);
int connectTCP(const char *host, int port);
#define LINELEN 256
int main(int argc, char *argv[])
{
char *host = "localhost";
int port = 3344;
pthread_t th;
int sock ;
switch (argc)
{
case 1:
host = "localhost";
break;
case 3:
port = atoi(argv[2]);
case 2:
host = argv[1];
break;
default:
fprintf(stderr, "usage: TCPecho[host[port]]\n");
exit(1);
}
sock = connectTCP(host, port);
printf("已连接到服务器,fd:%d\n",sock);
//启动接收线程
if (pthread_create(&th, NULL,(void *(*)(void *)) recvMsg, (void *)sock) < 0)
errexit("phread_create:%s\n", strerror(errno));
//循环处理输入字符
int outchars;
char buf[LINELEN + 1];
while (1)
{
if(sock==NULL)
errexit("与服务器断开连接:%s\n",strerror(errno)) ;
while (fgets(buf, sizeof(buf), stdin))
{
buf[LINELEN] = '\0';
int cc=sizeof buf;
//printf("要发送的数据大小:%d\n",cc);
if(write(sock, buf, sizeof buf)<0){
printf("发送信息出错\n");
errexit("send:%s\n", strerror(errno));
}
printf("--------\n发送完成\n\n");
fflush(stdout);
}
}
printf("回到主函数\n");
exit(0);
}
void *recvMsg(int fd)
{
int cc=0;
char buf[LINELEN + 1];
printf("进入接收线程,fd:%d\n",fd);
while (1)
{
memset(buf,'\0',sizeof(buf));
while (cc = read(fd, buf, sizeof buf))
{
if (cc < 0){
errexit("recv:%s\n", strerror(errno));
printf("接收信息出错\n");
break;
}
printf("%s",buf);
fflush(stdout);
}
}
printf("退出接收线程");
}
完整源代码:
服务器
客户端