Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
248
Task/Chat-server/C/chat-server.c
Normal file
248
Task/Chat-server/C/chat-server.c
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
int tsocket;
|
||||
struct sockaddr_in tsockinfo;
|
||||
fd_set status, current;
|
||||
void ClientText(int handle, char *buf, int buf_len);
|
||||
|
||||
struct client
|
||||
{
|
||||
char buffer[4096];
|
||||
int pos;
|
||||
char name[32];
|
||||
} *connections[FD_SETSIZE];
|
||||
|
||||
void AddConnection(int handle)
|
||||
{
|
||||
connections[handle] = malloc(sizeof(struct client));
|
||||
connections[handle]->buffer[0] = '\0';
|
||||
connections[handle]->pos = 0;
|
||||
connections[handle]->name[0] = '\0';
|
||||
}
|
||||
|
||||
void CloseConnection(int handle)
|
||||
{
|
||||
char buf[512];
|
||||
int j;
|
||||
|
||||
FD_CLR(handle, &status);
|
||||
|
||||
if (connections[handle]->name[0])
|
||||
{
|
||||
sprintf(buf, "* Disconnected: %s\r\n", connections[handle]->name);
|
||||
|
||||
for (j = 0; j < FD_SETSIZE; j++)
|
||||
{
|
||||
if (handle != j && j != tsocket && FD_ISSET(j, &status))
|
||||
{
|
||||
if (write(j, buf, strlen(buf)) < 0)
|
||||
{
|
||||
CloseConnection(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
printf ("-- Connection %d disconnected\n", handle);
|
||||
}
|
||||
if (connections[handle])
|
||||
{
|
||||
free(connections[handle]);
|
||||
}
|
||||
close(handle);
|
||||
}
|
||||
|
||||
void strip(char *buf)
|
||||
{
|
||||
char *x;
|
||||
|
||||
x = strchr(buf, '\n');
|
||||
if (x) { *x='\0'; }
|
||||
x = strchr(buf, '\r');
|
||||
if (x) { *x='\0'; }
|
||||
}
|
||||
|
||||
int RelayText(int handle)
|
||||
{
|
||||
char *begin, *end;
|
||||
int ret = 0;
|
||||
begin = connections[handle]->buffer;
|
||||
if (connections[handle]->pos == 4000)
|
||||
{
|
||||
if (begin[3999] != '\n')
|
||||
begin[4000] = '\0';
|
||||
else {
|
||||
begin[4000] = '\n';
|
||||
begin[4001] = '\0';
|
||||
}
|
||||
} else {
|
||||
begin[connections[handle]->pos] = '\0';
|
||||
}
|
||||
|
||||
end = strchr(begin, '\n');
|
||||
while (end != NULL)
|
||||
{
|
||||
char output[8000];
|
||||
output[0] = '\0';
|
||||
if (!connections[handle]->name[0])
|
||||
{
|
||||
strncpy(connections[handle]->name, begin, 31);
|
||||
connections[handle]->name[31] = '\0';
|
||||
|
||||
strip(connections[handle]->name);
|
||||
sprintf(output, "* Connected: %s\r\n", connections[handle]->name);
|
||||
ret = 1;
|
||||
} else
|
||||
{
|
||||
sprintf(output, "%s: %.*s\r\n", connections[handle]->name,
|
||||
end-begin, begin);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
if (output[0])
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < FD_SETSIZE; j++)
|
||||
{
|
||||
if (handle != j && j != tsocket && FD_ISSET(j, &status))
|
||||
{
|
||||
if (write(j, output, strlen(output)) < 0)
|
||||
{
|
||||
CloseConnection(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
begin = end+1;
|
||||
end = strchr(begin, '\n');
|
||||
}
|
||||
|
||||
strcpy(connections[handle]->buffer, begin);
|
||||
connections[handle]->pos -= begin - connections[handle]->buffer;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ClientText(int handle, char *buf, int buf_len)
|
||||
{
|
||||
int i, j;
|
||||
if (!connections[handle])
|
||||
return;
|
||||
j = connections[handle]->pos;
|
||||
|
||||
for (i = 0; i < buf_len; ++i, ++j)
|
||||
{
|
||||
connections[handle]->buffer[j] = buf[i];
|
||||
|
||||
if (j == 4000)
|
||||
{
|
||||
while (RelayText(handle));
|
||||
j = connections[handle]->pos;
|
||||
}
|
||||
}
|
||||
connections[handle]->pos = j;
|
||||
|
||||
while (RelayText(handle));
|
||||
}
|
||||
|
||||
|
||||
int ChatLoop()
|
||||
{
|
||||
int i, j;
|
||||
FD_ZERO(&status);
|
||||
|
||||
FD_SET(tsocket, &status);
|
||||
FD_SET(0, &status);
|
||||
|
||||
while(1)
|
||||
{
|
||||
current = status;
|
||||
if (select(FD_SETSIZE, ¤t, NULL, NULL, NULL)==-1)
|
||||
{
|
||||
perror("Select");
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < FD_SETSIZE; ++i)
|
||||
{
|
||||
if (FD_ISSET(i, ¤t))
|
||||
{
|
||||
if (i == tsocket)
|
||||
{
|
||||
struct sockaddr_in cliinfo;
|
||||
socklen_t addrlen = sizeof(cliinfo);
|
||||
int handle;
|
||||
handle = accept(tsocket, &cliinfo, &addrlen);
|
||||
if (handle == -1)
|
||||
{
|
||||
perror ("Couldn't accept connection");
|
||||
} else if (handle > FD_SETSIZE)
|
||||
{
|
||||
printf ("Unable to accept new connection.\n");
|
||||
close(handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (write(handle, "Enter name: ", 12) >= 0)
|
||||
{
|
||||
printf("-- New connection %d from %s:%hu\n",
|
||||
handle,
|
||||
inet_ntoa (cliinfo.sin_addr),
|
||||
ntohs(cliinfo.sin_port));
|
||||
FD_SET(handle, &status);
|
||||
|
||||
AddConnection(handle);
|
||||
}
|
||||
}
|
||||
} /* Read data, relay to others. */
|
||||
else
|
||||
{
|
||||
char buf[512];
|
||||
int b;
|
||||
|
||||
b = read(i, buf, 500);
|
||||
if (b <= 0)
|
||||
{
|
||||
CloseConnection(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClientText(i, buf, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* While 1 */
|
||||
}
|
||||
|
||||
int main (int argc, char*argv[])
|
||||
{
|
||||
tsocket = socket(PF_INET, SOCK_STREAM, 0);
|
||||
|
||||
tsockinfo.sin_family = AF_INET;
|
||||
tsockinfo.sin_port = htons(7070);
|
||||
if (argc > 1)
|
||||
{
|
||||
tsockinfo.sin_port = htons(atoi(argv[1]));
|
||||
}
|
||||
tsockinfo.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
printf ("Socket %d on port %hu\n", tsocket, ntohs(tsockinfo.sin_port));
|
||||
|
||||
if (bind(tsocket, &tsockinfo, sizeof(tsockinfo)) == -1)
|
||||
{
|
||||
perror("Couldn't bind socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen(tsocket, 10) == -1)
|
||||
{
|
||||
perror("Couldn't listen to port");
|
||||
}
|
||||
|
||||
ChatLoop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue