服务端
#include#include #include #include #include #include #include #include #include #include #define portnumber 3333 int main(int argc, char* argv[]) { int local_listen_socket, server_session_socket; struct sockaddr_in server_addr_info_struct; struct sockaddr_in client_addr_info_struct; int size_of_sockaddr_in; int read_got_bytes_nr; char buffer[1024]; if ((local_listen_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) { // AF_INET i.e. IPV4; SOCK_STREAM i.e. TCP fprintf(stderr, "Socket error:%sna", strerror(errno)); exit(1); } bzero(&server_addr_info_struct, sizeof(struct sockaddr_in)); // 初始化,置0 server_addr_info_struct.sin_family = AF_INET; // Internet server_addr_info_struct.sin_addr.s_addr = htonl(INADDR_ANY); // 将本机host上的long数据转化为网络上的long数据,使服务器程序能运行在不同CPU的主机上 // INADDR_ANY 表示主机监听任意/所有IP地址。 //server_addr_info_struct.sin_addr.s_addr=inet_addr("192.168.1.1"); //用于绑定到一个固定IP,inet_addr用于把数字加格式的ip转化为整形ip server_addr_info_struct.sin_port = htons(portnumber); // (将本机器上的short数据转化为网络上的short数据)端口号 if (bind(local_listen_socket, (struct sockaddr*)(&server_addr_info_struct), sizeof(struct sockaddr)) == -1) { fprintf(stderr, "ERR bind():%sna", strerror(errno)); exit(1); } if (listen(local_listen_socket, 5) == -1) { fprintf(stderr, "ERR listen():%sna", strerror(errno)); exit(1); } while (1) { size_of_sockaddr_in = sizeof(struct sockaddr_in); fprintf(stderr, "Listening & Accepting...n"); if ((server_session_socket = accept(local_listen_socket, (struct sockaddr*)(&client_addr_info_struct), &size_of_sockaddr_in)) == -1) { // 服务器阻塞, 直到接受到客户连接 fprintf(stderr, "ERR accept():%sna", strerror(errno)); exit(1); } fprintf(stderr, "Got connection from %sn", inet_ntoa(client_addr_info_struct.sin_addr)); // 网络地址 转换成 字符串 if ((read_got_bytes_nr = read(server_session_socket, buffer, 1024)) == -1) { fprintf(stderr, "ERR read():%sn", strerror(errno)); exit(1); } buffer[read_got_bytes_nr] = ' '; printf("Server received %sn", buffer); close(server_session_socket); } close(local_listen_socket); exit(0); }
客户端
#include多线程#include #include #include #include #include #include #include #include #include #define portnumber 3333 int main(int argc, char* argv[]) { int local_socket; char buffer[1024]; struct sockaddr_in server_addr; struct hostent* host; if (argc != 2) { fprintf(stderr, "Usage:%s hostname an", argv[0]); exit(1); } if ((host = gethostbyname(argv[1])) == NULL) { fprintf(stderr, "ERR gethostbynamen"); exit(1); } if ((local_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) { // AF_INET:Internet;SOCK_STREAM:TCP fprintf(stderr, "ERR socket:%san", strerror(errno)); exit(1); } bzero(&server_addr, sizeof(server_addr)); // 初始化,置0 server_addr.sin_family = AF_INET; // IPV4 server_addr.sin_port = htons(portnumber); // (将本机器上的short数据转化为网络上的short数据)端口号 server_addr.sin_addr = *((struct in_addr*)host->h_addr); // IP地址 if (connect(local_socket, (struct sockaddr*)(&server_addr), sizeof(struct sockaddr)) == -1) { fprintf(stderr, "ERR connect:%san", strerror(errno)); exit(1); } printf("Please typein a string:n"); fgets(buffer, 1024, stdin); write(local_socket, buffer, strlen(buffer)); close(local_socket); exit(0); }
server
#include#include #include #include #include #include #include #include #include #include #include #include //TODO: 某些头文件 #define MAX_BUFFER 1024 void* thread_function(void* arg_array) { int nr_bytes_read, char_index; char receive_and_send_buffer[MAX_BUFFER]; int* p_arg = (int*)arg_array; int thread_session_socket = *p_arg; printf("thread_session_socket = %dn", thread_session_socket); while (1) { nr_bytes_read = read(thread_session_socket, receive_and_send_buffer, MAX_BUFFER);//TODO: 尝试从socket读取 if (receive_and_send_buffer[0] == '#')//TODO: 如果错误,或没能从socket读取字符 break; printf("Message from client(%d): %sn", nr_bytes_read, receive_and_send_buffer); for (char_index = 0; char_index < nr_bytes_read; char_index++) receive_and_send_buffer[char_index] = toupper(receive_and_send_buffer[char_index]);//TODO: 转换为大写 write(thread_session_socket, receive_and_send_buffer, char_index);//TODO: 返回给客户端 } close(thread_session_socket);//TODO: 关闭socket return 0; } int main(int argc, char* argv[]) { socklen_t size_of_client_sockaddr; pthread_t tid; int listen_socket; int session_socket; int return_code; int port_number; struct sockaddr_in client_remote_sockaddr; struct sockaddr_in server_local_sockaddr; //服务器端运行时要给出端口信息,该端口为监听端口 if (argc != 2) { printf("Usage:%s port_number n", argv[0]); return 1; } //获得输入的端口 port_number = atoi(argv[1]); //创建套接字用于服务器的监听 listen_socket = (PF_INET, SOCK_STREAM, 0);//TODO: socket() if (listen_socket < 0) {//TODO: 如果出错 perror("ERR socket."); return 1; } //填充关于服务器的套节字信息 memset(&server_local_sockaddr, 0, sizeof(server_local_sockaddr)); server_local_sockaddr.sin_family = AF_INET; server_local_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); server_local_sockaddr.sin_port = htons(port_number); //将服务器和套节字绑定 return_code = bind(listen_socket, (struct sockaddr *)&server_local_sockaddr, sizeof(server_local_sockaddr));//TODO: 调用bind绑定地址和端口(提供服务的位置) if (return_code == -1) {//TODO: 如果出错 perror("ERR bind."); close(listen_socket);//TODO: 关闭监听socket return 1; } //监听指定端口,连接5个客户端 return_code = (listen_socket, 5);//TODO: 请求监听、提供服务 if (return_code == -1) {//TODO: 如果出错 perror("ERR listen."); close(listen_socket);//TODO: 关闭监听socket return 1; } //对每个连接来的客户端创建一个线程,单独与其进行通信。 //首先调用read函数读取客户端发送来的信息,将其转换成大写后发送回客户端,#退出。 while (1) { size_of_client_sockaddr = sizeof(client_remote_sockaddr); //TODO: 12345 改为自己的学号,此处不要修改write调用和STDOUT_FILENO参数! write(STDOUT_FILENO, "Listening & Accepting for 201930310030 ...n", strlen("Listening & Accepting for 201930310030 ...n")); return_code = accept(listen_socket, (struct sockaddr *)&client_remote_sockaddr, &size_of_client_sockaddr);//TODO: 调用accept阻塞,接到客户机时返回 session_socket if (return_code < 0) {//TODO: 如果出错 if (errno == EINTR) continue; else { perror("ERR accept(): cannot accept client connect request"); close(listen_socket);//TODO: 关闭socket return 1; } } printf("session_socket = %dn", session_socket); //打印建立连接的客户端产生的套节字 return_code = pthread_create(&tid, NULL, thread_function, &session_socket);//TODO: 调用 pthread_create,将 session_socket传递给 thread_function if (return_code == -1) {//TODO: 如果出错 perror("ERR pthread_create()"); close(listen_socket);//TODO: 关闭一个socket close(session_socket);//TODO: 关闭另一个socket return 1; } } return 0; }
client
#include#include #include #include #include #include #include #include //TODO: 某些头文件 #define MAX_BUFFER 1024 int main(int argc, char* argv[]) { int local_socket; int return_code; char send_and_receive_buffer[MAX_BUFFER]; int port_number; int nr_bytes_read; static struct sockaddr_in server_sockaddr; //客户端运行需要给出具体的连接地址和端口 if (argc != 3) { printf("Usage: %s server_ip_address port_number n", argv[0]); return 1; } //获得输入的端口 port_number = atoi(argv[2]); //创建套节字用于客户端的连接 local_socket = socket(PF_INET, SOCK_STREAM, 0);//TODO: 调用socket if (local_socket < 0) {//TODO: 如果错误 perror("ERR socket."); return 1; } //填充关于服务器的套节字信息 memset(&server_sockaddr, 0, sizeof(server_sockaddr)); server_sockaddr.sin_family = AF_INET; server_sockaddr.sin_addr.s_addr = inet_addr(argv[1]); server_sockaddr.sin_port = htons(port_number); //连接指定的服务器 return_code = (local_socket,(struct sockaddr *)&server_sockaddr, sizeof(server_sockaddr));//TODO: 调用connect if (return_code == -1) {//TODO: 如果错误 perror("ERR connect."); close(local_socket); return 1; } memset(send_and_receive_buffer, 0, MAX_BUFFER); //用户输入信息后,程序将输入的信息通过套接字发送给服务器 ,然后调用read函数从服务器中读取发送来的信息。 //输入“#”退出 while (1) { //TODO: 12345 改为自己的学号,此处不要修改write调用和STDOUT_FILENO参数! write(STDOUT_FILENO, "Type in a string for 201930310030:", strlen("Type in a string for 201930310030:")); nr_bytes_read = read(STDOUT_FILENO, send_and_receive_buffer, MAX_BUFFER);//TODO: 调用read, 从STDIN_FILENO读 if (nr_bytes_read > 0) write(local_socket, send_and_receive_buffer, nr_bytes_read);//TODO: 调用write,写socket nr_bytes_read = read(local_socket, send_and_receive_buffer, nr_bytes_read);//TODO: 调用read,读socket if (nr_bytes_read > 0) printf("Message form server: %sn", send_and_receive_buffer); if (send_and_receive_buffer[0] == '#') break; //提示:刚才几句忽略了某些可能的错误,你能加上么? } close(local_socket); return 0; }



