// testserver.cpp : 定义控制台应用程序的入口点。
//
//#include "stdafx.h"
/* For sockaddr_in */
#include
/* For socket functions */
#include
/* For fcntl */
#include
/* for select */
#include
#include
#include
#include
#include
#include
#include
#define MAX_LINE 16384
struct fd_state {
char buffer[MAX_LINE];
size_t buffer_used;
int writing;
size_t n_written;
size_t write_upto;
};
struct fd_state *
alloc_fd_state(void)
{
struct fd_state *state = malloc(sizeof(struct fd_state));
if (!state)
return NULL;
state->buffer_used = state->n_written = state->writing =
state->write_upto = 0;
return state;
}
void
free_fd_state(struct fd_state *state)
{
free(state);
}
void
make_nonblocking(int fd)
{
fcntl(fd, F_SETFL, O_NONBLOCK);
}
int
do_onlyread(int fd, struct fd_state *state)
{
char buf[1024];
int i;
ssize_t result;
while (1) {
result = recv(fd, buf, sizeof(buf), 0);
if (result <= 0)
break;
printf("read %s from fd %d \n", buf, fd);
}
if (result == 0) {
return 1;
}
else if (result < 0) {
if (errno == EAGAIN)
return 0;
return -1;
}
return 0;
}
int
do_read(int fd, struct fd_state *state)
{
char buf[1024];
int i;
ssize_t result;
while (1) {
result = recv(fd, buf, sizeof(buf), 0);
if (result <= 0)
break;
for (i = 0; i < result; ++i) {
if (state->buffer_used < sizeof(state->buffer))
state->buffer[state->buffer_used++] = buf[i];
if (buf[i] == '\n') {
state->writing = 1;
state->write_upto = state->buffer_used;
state->buffer[state->buffer_used] = 0;
//printf("read %s from fd %d \n ", buf,fd);
}
}
}
if (result == 0) {
return 1;
}
else if (result < 0) {
if (errno == EAGAIN)
return 0;
return -1;
}
return 0;
}
int
do_write(int fd, struct fd_state *state)
{
while (state->n_written < state->write_upto) {
ssize_t result = send(fd, state->buffer + state->n_written,
state->write_upto - state->n_written, 0);
if (result < 0) {
if (errno == EAGAIN)
return 0;
return -1;
}
assert(result != 0);
state->n_written += result;
}
if (state->n_written == state->buffer_used)
state->n_written = state->write_upto = state->buffer_used = 0;
state->writing = 0;
return 0;
}
void
run(void)
{
int listener;
struct fd_state *state[FD_SETSIZE];
struct sockaddr_in sin;
int i, maxfd;
fd_set readset, writeset, exset;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = 0;
sin.sin_port = htons(40713);
for (i = 0; i < FD_SETSIZE; ++i)
state[i] = NULL;
listener = socket(AF_INET, SOCK_STREAM, 0);
make_nonblocking(listener);
#ifndef WIN32
{
int one = 1;
setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
}
#endif
if (bind(listener, (struct sockaddr*)&sin, sizeof(sin)) < 0) {
perror("bind");
return;
}
if (listen(listener, 2)<0) {
perror("listen");
return;
}
FD_ZERO(&readset);
FD_ZERO(&writeset);
FD_ZERO(&exset);
while (1) {
maxfd = listener;
FD_ZERO(&readset);
FD_ZERO(&writeset);
FD_ZERO(&exset);
FD_SET(listener, &readset);
for (i = 0; i < FD_SETSIZE; ++i) {
if (state[i]) {
if (i > maxfd)
maxfd = i;
FD_SET(i, &readset);
if (state[i]->writing) {
FD_SET(i, &writeset);
//else
//FD_SET(i, &writeset);
}
}
}
if (select(maxfd + 1, &readset, &writeset, &exset, NULL) < 0) {
perror("select");
return;
}
if (FD_ISSET(listener, &readset)) {
struct sockaddr_storage ss;
socklen_t slen = sizeof(ss);
int fd = accept(listener, (struct sockaddr*)&ss, &slen);
if (fd < 0) {
perror("accept");
}
else if (fd > 5) {
printf("only support 2 file fd %d closed\n", fd);
close(fd);
}
else {
printf("fd %d connect\n", fd);
make_nonblocking(fd);
state[fd] = alloc_fd_state();
assert(state[fd]);/*XXX*/
}
}
for (i = 0; i < maxfd + 1; ++i) {
int r = 0;
if (i == listener)
continue;
if (FD_ISSET(i, &readset)) {
if ((i == 4) && (state[5]!=NULL))
r = do_read(i, state[5]);
else if((i == 5) &&(state[4]!=NULL))
r = do_read(i, state[4]);
else
r = do_onlyread(i, state[i]);
}
if (r) {
free_fd_state(state[i]);
state[i] = NULL;
printf("fd %d closed\n", i);
close(i);
}
r = 0;
if (FD_ISSET(i, &writeset)) {
printf("fd %d wirte ", i);
r = do_write(i, state[i]);
}
if (r) {
free_fd_state(state[i]);
state[i] = NULL;
printf("fd %d closed\n", i);
close(i);
}
}
}
}
int
main(int c, char **v)
{
setvbuf(stdout, NULL, _IONBF, 0);
run();
return 0;
}
python测试程序
# -*- coding: utf-8 -*-
'''
This is a testing program
the program is used to test socket client
'''
import socket
import sys
import threading
def tcprecv(tcp_client):
while True:
(message, address) = tcp_client.recvfrom(8192)
print("Got data from", str(tcp_client.getpeername()), ": ", message.decode())
def start_tcp_client(ip, port):
#server port and ip
server_ip = ip
server_port = port
tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serveraddr = (server_ip,server_port)
try:
tcp_client.connect(serveraddr)
except socket.error:
print( 'fail to setup socket connection')
return
rthread = threading.Thread(target=tcprecv,args=(tcp_client,))
rthread.start()
while True:
msg = input()
if not msg:
break
msg = msg+'\n'
tcp_client.send(msg.encode())
tcp_client.close()
start_tcp_client("xx.xx.xx.xx",40713)